CI/CD For Azure Functions App By Using GitHub And Azure DevOps

This post was first published at Medium

In the previous post, we created an Azure functions app using .Net Core 3.1 with VS Code and published our app to Azure cloud by so-called right-click publishing. To be honest, although right-click publishing is a good way to quickly build prototypes, it is not suitable for real-world development, especially when there are multiple developers in a team. Therefore, an automated process is very important, because it provides us with a reliable, repeatable, and faster process of building artifacts.

This post details the process of using Azure DevOps to implement the CI/CD pipeline for our Azure Functions app project created in the previous post, the issues encountered in the process (of course they are solved 😃), and how to add the build/deployment status badges to our GitHub repo. You can find the repo here:

Create A Project On Azure DevOps

We can manage our Azure resources at the Azure portal website, on the other hand, Azure DevOps has its own website, which is here

Therefore, we should create an organization and a project on the Azure DevOps website first.

As you can see above, I created an organization named Jiadong Chen and a new project named AzureFunction.UserCRUD. It’s a public project which means everyone can access this project, and you can find it here:

Now we set up our Azure DevOps organization and project. Next, we will use the template provided by Azure to create the Azure Pipeline we need.

Connect To GitHub And Create The Azure Pipeline We Need

Now let’s come back to the Azure portal website and open the Azure Functions app services page we created before. You can find there is a button called Deployment Center under the Deployment section. If you’ve not set up your CI/CD pipeline for your app, then you will be asked to select the source control provider. In this post, we will use GitHub as our source control provider.

Then we need to select the build provider, for the sake of using Azure DevOps we will select the Azure Pipelines(Preview) (wait, preview? So is this the reason for the issues later?)

After selecting the build provider, we need to configure the deployment pipeline for our app. At the configure page we can select the GitHub repo/branch at the Code section and select the DevOps Project we created on the Azure DevOps website at the Build section.

What you should notice is that the default Function App Type is the script app, therefore, for our app using .Net Core 3.1, we should select the Precompiled .NET Function App type.

Now, the deployment pipeline for our app is set up and it should run automatically. However, if your app is created with VS Code and using .NET Core 3.0 or later, you may encounter some issues that I encountered and the first build maybe FAILED.

The Azure Pipeline

Let’s come back to the Azure DevOps website and check our project created on the site.

As you can see above, a CI pipeline already set up. You can view the pipeline structure in a YAML format. A typical hierarchy in the structure of a YAML file looks like:

  **Stage** A   
    **Job** 1   
      **Step** 1.1   
      Step 1.2   
    Job 2   
      Step 2.1

A pipeline is one or more stages that describe a CI/CD process. Stages are the major divisions in a pipeline such as Build, Test. A stage is one or more jobs, which are units of work assignable to the same machine. A job is a linear series of steps. Steps can be tasks, scripts, or references to external templates.

And our pipeline is relatively simple, and the following is the YAML file(If you don’t like to read the following YAML file, just skip it).

  name: Azure Pipelines  
  - msbuild  
  - visualstudio  
  - vstest**steps**:  
\- task: NuGetToolInstaller@1  
  displayName: 'Use NuGet 5.0.0'  
    versionSpec: 5.0.0\- task: NuGetCommand@2  
  displayName: 'NuGet restore'  
    restoreSolution: '$(Parameters.solution)'\- task: VSBuild@1  
  displayName: 'Build solution'  
    solution: '$(Parameters.solution)'  
    msbuildArgs: '/p:DeployOnBuild=true /p:DeployDefaultTarget=WebPublish /p:WebPublishMethod=FileSystem /p:publishUrl="$(Agent.TempDirectory)\\WebAppContent\\\\"'  
    platform: '$(BuildPlatform)'  
    configuration: '$(BuildConfiguration)'\- task: ArchiveFiles@2  
  displayName: 'Archive Files'  
    rootFolderOrFile: '$(Agent.TempDirectory)\\WebAppContent'  
    includeRootFolder: false\- task: VSTest@2  
  displayName: 'Test Assemblies'  
    testAssemblyVer2: |  
    platform: '$(BuildPlatform)'  
    configuration: '$(BuildConfiguration)'\- task: PublishSymbols@1  
  displayName: 'Publish symbols path'  
    SearchPattern: '\*\*\\bin\\\*\*\\\*.pdb'  
  continueOnError: true\- task: PublishBuildArtifacts@1  
  displayName: 'Publish Artifact'  
    PathtoPublish: '$(build.artifactstagingdirectory)'  
    ArtifactName: '$(Parameters.ArtifactName)'

As you can see above, there is no pipeline, no stages, and no jobs. Why?

This is because our pipeline only has only a stage and a single job, so we can omit the stages and jobs keywords and directly specify the steps keyword.

Now we have an understanding of the pipeline we are using. Next let’s take a look at the first issue you may encounter.

I’m using Visual Studio Code Instead Of Visual Studio

The first issue you may encounter is the pipeline doesn’t find the solution file in our app project.

It’s right because our project doesn’t include a solution file. The Azure Functions project created by using the Azure Functions extension in VS Code only generates a csproj file.

Therefore, we should modify the Path to solution or packages parameter from **\*.sln to **\*.csproj .

Cool. Now the Solution not found using search pattern ‘d:\a\1\s\**\*.sln’ error is gone!

I Need .NET Core 3.1!

The second issue you may encounter is the ‘NETSDK1045’ error, specifically the current .NET SDK does not support targeting .NET Core 3.1.

If you look at the default Agent Specification of our pipeline, you will find the default one is vs2017-win2016. And if we want to use .NET Core 3.1, we need to use vs2019 instead of vs2017. Therefore, we should select windows-2019 as the Agent Specification. This is because windows-2019 specification uses Windows Server 2019 with Visual Studio 2019 image on Azure.

Run the pipeline again, and it SUCCEEDED.YEAH!

And the CD pipeline runs successfully, too.

Add Status Badges To The GitHub Repo

Now with Azure DevOps, we can continuously integrate our code and continuously deliver our app. And moreover, we can add the build and deployment status badges to our GitHub repo to reflect the current status of our project.

At first, let’s get the build status badge from Azure DevOps. You can find it at the Options panel of the Build pipeline(CI pipeline).

There are Markdown link and Image URL, for the sake of displaying at our GitHub repo, we should copy & paste the Markdown link to the file of our repo.

Next, we can get the deployment status badge from the Release pipeline(CD pipeline). You can find it at the Options panel, then select Integrations and check the Enable the deployment status badge. And the Production badge is what we are looking for!

After adding these badges URL to our file, then the GitHub repo looks like the following image.COOL!

Thanks for reading and hope it’s helpful!

Have a chat at

Subscribe To Jiadong Chen's Blog

Jiadong Chen
Senior Software Developer

Husbandã…£Programmerã…£Authorã…£Bloggerã…£Speakerã…£Microsoft @MVPAward In Developer Technologiesã…£Previously @Unity3d ã…£Opinions = my own.

comments powered by Disqus