Home > Net >  Azure pipeline Multi Stage set build Number as part of the stage name
Azure pipeline Multi Stage set build Number as part of the stage name

Time:03-17

I am working on a multi stage pipeline that build and deploy some c# code from staging to production

Everything works just fine but I wanted to try and customise a bit more the pipeline so I can see the actual version that is being built and deployed as part of the name of the stage.

At the current stage, this my multi stage pipeline

trigger:
  batch: true
  tags:
    include:
      - '*'
  branches:
    exclude:
      - main
      - staging

pool:
  vmImage: 'ubuntu-latest'
variables:
  buildNumber: "$[variables['Build.BuildNumber']]"
  DOCKER_BUILDKIT: 1
  dockerRegistryServiceConnectionStaging: '<My-Connection-String>'
  imageRepositoryStaging: '<My-Repo-Name>'
  containerRegistryStaging: '<My-Container-Name>'

  dockerRegistryServiceConnectionProd: '<My-Connection-String>'
  imageRepositoryProd: 'My-Repo-Name>'
  containerRegistryProd: '<My-Container-Name>'
  dockerfilePath: 'pathTo/Dockerfile'
  solution: 'path/To/Solution.csproj'
  tag: '$(Build.BuildNumber)'

stages:
- stage: 'Build_Staging'
  displayName: 'Build_Staging'
  jobs:
  - job: buildStaging
    displayName: 'DotNet Core publish and dockerize'

    steps:
    - powershell: |
        # Write your PowerShell commands here.
        
        Write-Host "Update Build.BuildNumber"
        cd $(System.DefaultWorkingDirectory)
        $Latesttag = $(git describe --tags $(git rev-list --tags --max-count=1))
        Write-Host "The latest git tag is $Latesttag "
        Write-Host
        "##vso[build.updatebuildNumber]$Latesttag"
    - task: DotNetCoreCLI@2
      displayName: 'DotNet - Restore'
      inputs:
        command: 'restore'
        projects: $(solution)
        noCache: true
        versioningScheme: 'off'
        vstsFeed: '<Feed>'

    - task: DotNetCoreCLI@2
      name: 'DotnetPublish'
      displayName: 'dotnet - Publish'
      inputs:
        command: 'publish'
        projects: $(solution)
        arguments: '-o publish/solution -c release'
        modifyOutputPath: false
        zipAfterPublish: false
        publishWebProjects: false
        
    - task: Docker@2
      name: 'dockerBuildAndPush'
      displayName: 'docker - Build & Push $(tag)'
      inputs:
        repository: $(imageRepositoryStaging)
        Dockerfile: $(dockerfilePath)
        containerRegistry: ${{ variables.dockerRegistryServiceConnectionStaging }}
        buildContext: ${{ variables.buildContext }}
        tags: |
          $(Build.BuildNumber)
          latest
          
- stage: 'Deploy_Staging'
  jobs: 
  - deployment: 'Deploy'
    environment: 'Staging'
    variables:
      EnvironmentName: 'Staging'
    strategy:
      runOnce:
        deploy:     
          steps:
          - task: AzureRmWebAppDeployment@4
            displayName: 'Deploy Azure App Service To Staging'
            inputs:
              azureSubscription: '<Azure-Subscription>'
              appType: 'webAppContainer'
              DockerNamespace: '<container-namespace>'
              DockerRepository: '<Repository>'
              DockerImageTag: '$(Build.BuildNumber)'
              WebAppName: '<WebAppName>'

The Powershell command is to override the Build.BuildNumber with the tag I am pushing to GitHub.

When I run this pipeline, in azure DevOps, I see the stage name Build_Staging_$(Build.BuildNumber) as a string.

What I would really like to see is, if I push the tag 'v1.0.0` for example, is to see the stage name like:

Build_Staging_v1.0.0

I tried to use the displayName and the output is not the one I was looking for and if I try with name instead of displayName I get the error unexpected value name

Can please please anyone help understand what am I doing wrong and how I can achieve this?

Please if my question is not 100% clear and missing any important detail, just let me know

UPDATE:

I did update the post with my entire pipeline. This pipeline, before it used to be a single job process, and everything was working fine. But to get my hand dirty, I wanted to add stages to split and workflow based on resources and environment.

The process is still working and this is what I am expecting.

In my GitHub, when I create a tag on the main branch, this will trigger my build stage. Which thanks to the Powershell script to update the BuildNumber with the tag, I am able to build the docker image in my container registry in the following format:

docker-image-name:v1.0.1

That version can be seen at this level also:

enter image description here

This updated buildNumber (now is Tag) is use in Azure pipelines App Slack to check the version that has been pushed.

So far everything is good.

But I am facing the problem with the deployment job, at that level I am not able to set any Powershell script to update that same BuildNumber with the tag. I checked the documentation and nothing is mentioned about how I can add another job or step. I tried implementing this but I get errors that the value is unexpected.

Let me just share another screenshot to fully explain the issue.

Assuming I am deploying the docker image v1.0.1, everything works perfectly, but the build number in deployment stage, is not being updated, in fact in slack channel, I see the normal build number, as follow:

enter image description here

Instead of having the buildNumber, I would like to have my tag.

Please any help here?

CodePudding user response:

Unfortunately, you won't be able to set a stage name to a dynamic variable that is set within one of its child's steps. You'll have to set it to a pipeline-level variable or predefined variable

Variable evaluation goes top-down from stages to tasks:

  • stages
    • jobs
      • tasks

To help explain exactly why, let's talk about how variable evaluation works in general with regard to this structure:

  • VARIABLE EVALUATION: Using stages as an example, you can set a stage name using any dynamic value that's present when the stage is evaluated. This means the variable is only accessed when the stage is initially "rendered". Azure DevOps requires that the variable be present before evaluation and will not retroactively update the UI if that variable is changed within a child step.

Let's talk about each and their respective limitations on what variables you can use in their names:

  • STAGES: pipeline-level variables, parameters (in the case of templates), or predefined variables

  • JOBS: stage-level variables, pipeline-level variables, parameters (in the case of templates), or predefined variables

  • TASKS: job-level variables, stage-level variables, pipeline-level variables, parameters (in the case of templates), or predefined variables

CodePudding user response:

I did something similar by setting my build number to a repo tag. Here is the PowerShell function that sets the Build.Buildnumber variable to the tag value. You can just call it straight out or base it off a parameter if you have other version number logic.

   function getTagVersion() {
      $tag = iex "git describe --long --tags --always"
      $a = [regex]"\d \.\d \.\d \.\d "
      $b = $a.Match($tag)
      $b = $b.Captures[0].value
      $b = $b -replace '-', '.'
      $b = $b -replace 'v', ''
      Write-Host "Version found: $b"
      $newBuildNumber = '$(Build.BuildNumber)' -replace $a,$b
      Write-Host "##vso[build.updatebuildnumber]$newBuildNumber"
      return $b
   }

I can't claim credit for this code as I found it on someone's blog. But it works and I use for my release builds. You just have to call the function and it will reset the build.buildnumber to the latest tag in your repo. Its important to note, that the tag should be in normal version number format.

Example: Tag Name: 10.1.100.0

  • Related