azure-devops-project-release

Azure DevOps Project Release and Deploy

In this post I am going to explore how to release and deploy the project in Azure DevOps board project after all work items has been moved to Done status and tested.

There are two possibility to release project:

  1.  Release locally on Visual Studio and deploy manually to the production environment.
  2. Release in Azure DevOps by creating Azure pipeline, release and deploy automatically to the production environment.

Release locally on Visual Studio and deploy manually

DevOps projects Usually are developing in Visual Studio, when a Work Item is assign to a developer, then developer, works on Item in Visual Studio and then checks in the assigned Item and moves item to the done in DevOps.

By locally release means here that you can build and release the project and takes the Release library to the production environment. Release shall be done by giving a Release name and label for for release to separate different releases. This is a possibility for a small company do that without so much work to done.

Release in Azure DevOps by creating Azure pipeline and deploying automatically

Releasing and deploying a project in Azure DevOps involves several steps. Here’s a general overview:

  1. Create and Manage Boards: In Azure DevOps, start by creating work items on your board to manage tasks, features, or user stories. Use boards to track progress, assign tasks, and collaborate with your team.
  2. Version Control: Use Azure Repos for version control to manage your codebase. This includes branches for features, bug fixes, etc. It’s crucial to have a proper branching strategy to ensure smooth deployment.
  3. Build Pipelines: Set up a build pipeline in Azure Pipelines. This involves defining how your code is built, tested, and packaged. You can automate the build process whenever changes are made to the codebase.
    • Select Project: Pipelines: Pipeline
    • press to Create Pipeline
    • Select Azure Repos Git (Yaml)
    • Then shows your project (ProductMicroservice) which you have created before
    • Select this Project (Repo) then show the following yaml file:
    • # ASP.NET Core (.NET Framework)
      # Build and test ASP.NET Core projects targeting the full .NET Framework.
      # Add steps that publish symbols, save build artifacts, and more:
      # https://docs.microsoft.com/azure/devops/pipelines/languages/dotnet-core
      
      trigger:
      - master
      
      pool:
        vmImage: 'windows-latest'
      
      variables:
        solution: '**/*.sln'
        buildPlatform: 'Any CPU'
        buildConfiguration: 'Release'
      
      steps:
      - task: NuGetToolInstaller@1
      
      - task: NuGetCommand@2
        inputs:
          restoreSolution: '$(solution)'
      
      - task: VSBuild@1
        inputs:
          solution: '$(solution)'
          msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:DesktopBuildPackageLocation="$(build.artifactStagingDirectory)\WebApp.zip" /p:DeployIisAppPath="Default Web Site"'
          platform: '$(buildPlatform)'
          configuration: '$(buildConfiguration)'
      
      - task: VSTest@2
        inputs:
          platform: '$(buildPlatform)'
          configuration: '$(buildConfiguration)'
    • After that you have edited then under Run press to save button to save or press to Variables to define new variables.
    • Press to Run button to run the pipeline
    • Select branch and press to Run button.
    • Then starts to run it takes some seconds (minutes) then shows some results In the same time you can receive a mail from azure devops how the pipeline running has been gone.
    • Press to jobs, to see more detail.

Edit the yaml file to see the better  structure:

# ASP.NET Core (.NET Framework)
# Build and test ASP.NET Core projects targeting the full .NET Framework.
# Add steps that publish symbols, save build artifacts, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/dotnet-core
name: ProductMicroservice-CI

trigger:
  branches:
   include:
   - master
   

pool:
  vmImage: 'windows-latest'

variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'

steps:
- task: DotNetCoreCLI@2



  inputs:
   command: 'restore'
   projects: '**/ProductMicroservice*.csproj'
  displayName: 'Restore Nuget Packages'
- task: DotNetCoreCLI@2

  inputs:
   command: 'build' 
   projects: '**/ProductMicroservice*.csproj'
   arguments: '--no-restore'
  displayName: 'Build projects'
- task: DotNetCoreCLI@2

  inputs:
   command: 'publish'
   publishWebProjects: false
   projects: '**/ProductMicroservice.csproj'
   arguments: '--configuration $(buildConfiguration) --no-restore'
   modifyOutputPath: false
  displayName: 'Publish ProductMicroservice'

The name section is name for Pipeline Name: ProductMicroservice-CI The trigger section defines that the pipeline is automatically triggered when something changes on the master branch inside the ProductMicroservice folder. The pool section defines that the pipeline is executed on an Windows agent and the variables section lets you define variables for the pipeline. By default, only the buildConfiguration is set to Release. The yaml file is saved in the Repos with name azure-pipeline.yml

In the steps: first and second Tasks Restore and executes a dotnet build in and sets the configuration to Release by using the previously defined buildConfiguration variable.

In the third Task Publishes , and display name (ProductMicroservice) is set to identify the step easier in the logs.

Additional  steps for CI Pipeline

I have added new steps to restore NuGet packages, build the solution, and publish the solution. The publish step should only be run when the pipeline was triggered by the master branch.

Now  time is run pipeline by pressing to  Save and Run the pipeline will be added to your source control and then executed.

It takes a little time and  then shows the result, for Summary (with som warnings).

azure-devops-project-release-2.png

Check Continuous Integration

  1. Click on pipeline, then click on 3 dots and click edit  then opens the Pipline and shows Variables and Run in the  upper right
  2. Click on 3 dots at top and click Trigger  and then check the checkbox: Override the YAML continuous integration trigger from here
    Enable continuous integration
    3. press to Save under “Save and Quit)
  3. then  shows Continuous Integration is enabled so this means whenever we do a commit to git repository it will automatically trigger a build shown as following figure:
azure-devops-project-release-3.png
Continuous Integration is enabled

 

Do a comment to test CI (Continuous Integration) in Visual Studio for a  file (e.g. IProductRepository .cs) commit this  to Git and then push it to DevOps repository, back to the Azure DevOps and click on Pipelines: shows the ProductMicroservice begins to build the pipeline, by showing  just running in the right side of Pipe line, when it finished press to the ProductMicroservice just has been done, in the menu then shows the newly run Pipeline as shown in the following figure:

azure-devops-project-release-4.png
Newly run Pipeline which shows the time and comment has been don in VS

Run Tasks only when the Master Branch triggered the build and succeeded

As we created we modified the YAML file the  publish task runs always, even if we don’t want to create a release.

I want  the pipeline to be more efficient to run this task only when the build was triggered by the master branch. To do that, we should add a custom condition to the publish task. I want to run the publish only when the previous steps succeeded and when the build was not triggered by a pull request. we do this with the following code:

task: DotNetCoreCLI@2
  inputs:
    command: 'publish'
    publishWebProjects: false
    projects: '**/ProductMicroservice.csproj'
    arguments: '--configuration $(buildConfiguration) --no-restore'     modifyOutputPath: false
  displayName: 'Publish ProductMicroservice`
  condition: and(succeeded(), ne(variables['Build.Reason'],'PullRequest'))

and the final YAML file is as following:

# ASP.NET Core (.NET Framework)
# Build and test ASP.NET Core projects targeting the full .NET Framework.
# Add steps that publish symbols, save build artifacts, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/dotnet-core
name: ProductMicroservice-CI

trigger:
  branches:
   include:
   - master
   

pool:
  vmImage: 'windows-latest'

variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'

steps:
- task: DotNetCoreCLI@2

#Restore

  inputs:
   command: 'restore'
   projects: '**/ProductMicroservice*.csproj'
  displayName: 'Restore Nuget Packages'
- task: DotNetCoreCLI@2
#build
  inputs:
   command: 'build' 
   projects: '**/ProductMicroservice*.csproj'
   arguments: '--no-restore'
  displayName: 'Build projects'
- task: DotNetCoreCLI@2

  # Publish
  inputs:
    command: 'publish'
    publishWebProjects: false
    projects: '**/ProductMicroservice.csproj'
    arguments: '--configuration $(buildConfiguration) --no-restore'
    modifyOutputPath: false
  displayName: 'Publish ProductMicroservice'
  condition: and(succeeded(), ne(variables['Build.Reason'],'PullRequest'))
HOW TO GET THE PUBLISHED FILE FROM THE AZURE DEVOPS PIPELINE?

Publish Artifact

What is Azure Artifact?

Azure Artifacts enables developers to share their code efficiently and manage all their packages from one place. With Azure Artifacts, developers can publish packages to their feeds and share it within the same team, across organizations, and even publicly.

you have to change the #Publish part with the following:

inputs:
    command: 'publish'
    publishWebProjects: false
    projects: '**/ProductMicroservice.csproj'
    arguments: '--configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)'
    zipAfterPublish: True
    modifyOutputPath: false
  displayName: 'Publish ProductMicroservice'
  condition: and(succeeded(), ne(variables['Build.Reason'],'PullRequest'))

And add the following in the end of yaml file:

task: PublishBuildArtifacts@1
  inputs:
    pathToPublish: '$(Build.ArtifactStagingDirectory)'
    artifactName: ProductMicroserviceArtfact
  displayName: 'PublishBuildArtifacts for ProductMicroservice'
- task: DownloadBuildArtifacts@0
  inputs: 
    buildType: 'current'
    downloadType: 'single'
    artifactName: 'ProductMicroserviceArtfact'
    downloadPath: '$(System.ArtifactDirectory)'
  displayName: 'DownloadBuildArtifacts for ProductMicroservice'

The final Pipeline  yaml file is as follow:

# ASP.NET Core (.NET Framework)
# Build and test ASP.NET Core projects targeting the full .NET Framework.
# Add steps that publish symbols, save build artifacts, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/dotnet-core
name: ProductMicroservice-CI

trigger:
  branches:
   include:
   - master
   

pool:
  vmImage: 'windows-latest'

variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'

steps:
- task: DotNetCoreCLI@2



  inputs:
   command: 'restore'
   projects: '**/ProductMicroservice*.csproj'
  displayName: 'Restore Nuget Packages'
- task: DotNetCoreCLI@2

  inputs:
   command: 'build' 
   projects: '**/ProductMicroservice*.csproj'
   arguments: '--no-restore'
  displayName: 'Build projects'
- task: DotNetCoreCLI@2

   
   
  inputs:
    command: 'publish'
    publishWebProjects: false
    projects: '**/ProductMicroservice.csproj'
    arguments: '--configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)'
    zipAfterPublish: True
    modifyOutputPath: false
  displayName: 'Publish ProductMicroservice'
  condition: and(succeeded(), ne(variables['Build.Reason'],'PullRequest'))

- task: PublishBuildArtifacts@1
  inputs:
    pathToPublish: '$(Build.ArtifactStagingDirectory)'
    artifactName: ProductMicroserviceArtfact
  displayName: 'PublishBuildArtifacts for ProductMicroservice'
- task: DownloadBuildArtifacts@0
  inputs: 
    buildType: 'current'
    downloadType: 'single'
    artifactName: 'ProductMicroserviceArtfact'
    downloadPath: '$(System.ArtifactDirectory)'
  displayName: 'DownloadBuildArtifacts for ProductMicroservice'

After running of pipeline we see “1 artifact producude”, press to this you can find a file with name: environment-variables.text which contains all environment definitions but there is no binary code to download and run it.

azure-devops-project-release-5.png
Artifact is published and ready for download

Now press to the 1 artifact link then shows ProductMicroserviceArtifact and under this you see a.zip file, press to this to download it

Unzip this file then you have the release of ProductMicroservice, take this somewhere in the C drive (e.g C:/tmp/a)

Then run command Prompt with following command:

dotnet ProductMicroservice.dll as seen in  the following figure:

azure-devops-project-release-6.png

Start browser with URL: http://localhost:5000, then shows page as following:

azure-devops-project-release-7.png

 

This was the process of CI  Pipeline in Azure DevOps and how to run Pipleline and create an Artifact file as a release.

 

Conclusion

In this post I have explored Release process of Project in Azure DevOps, in locally or Automated Release.

In Automated release we have learned the following:

  • How to create Azure Pipeline for build
  • How to enable CI (Continuously Integration )
  • How to do a Release Pipeline (create an Artifact)
  • How to deploy to production. (Get the Artifact to the production environment) automatic release.

The next  post is Integration of Azure Devops with VS Code  How to clone azure-devops project to VS Code

This post is part of  Azure DevOps Agile Boards step by step

Back to home page

 

Leave a Reply

Your email address will not be published. Required fields are marked *