azure-devopsmsbuildazure-pipelinesdotnetcorecli

Retrieving project version from csproj in Azure Pipeline .NET Core CLI task


I have the following tasks in my yaml file in Azure DevOps It publishes my console application and zip it in a file

- task: DotNetCoreCLI@2
  inputs:
    command: 'publish'
    publishWebProjects: false
    projects: '**/MyApp.csproj'
    arguments: '-r win-x64 -p:PublishSingleFile=True --self-contained true -o $(Build.ArtifactStagingDirectory)'

- task: PublishBuildArtifacts@1
  inputs:
    PathtoPublish: '$(Build.ArtifactStagingDirectory)'
    ArtifactName: 'drop'
    publishLocation: 'Container'

I set the project version directly on the project file in Visual Studio when I make any changes. Now I'm trying to get that version when I am publishing the project in AzureDevOps and customise the file name, lets say for a project version 1.2.1 the archived file output of the publish in azure should be MyApp-v1.2.1.zip Currently it only output file as MyApp.zip

Not sure if even my approach towards versioning is correct, so appreciate any input!

Updated:

Unfortunately the provided answer didn't work for me, I can get the version but I cannot rename the file, even copying the exact script below results in the same zip file, not renamed! The folder will be renamed but the zip file stays as MyApp.zip.

I have the following script now, trying to rename using PowerShell at the end but that successfully finish executing and again results in exact the same MyApp.zip file in the drop folder


- task: PowerShell@2
  inputs:
    targetType: 'inline'
    script: |
         $xml = [Xml] (Get-Content .\MyApp\MyApp.csproj)
         $version = $xml.Project.PropertyGroup.Version
         echo $version
         echo "##vso[task.setvariable variable=version]$version"

- task: DotNetCoreCLI@2
  inputs:
    command: 'publish'
    publishWebProjects: false
    projects: '**/MyApp.csproj'
    arguments: '-r win-x64 -p:PublishSingleFile=True --self-contained true -o $(Build.ArtifactStagingDirectory)'

- task: PublishBuildArtifacts@1
  displayName: 'Publish Artifact'
  inputs:
    PathtoPublish: '$(build.artifactstagingdirectory)'
  condition: succeededOrFailed()
  
- task: PowerShell@2
  inputs:
    targetType: 'inline'
    script: 'Rename-Item -Path "$(Build.ArtifactStagingDirectory)\MyApp.zip" -NewName "$(Build.ArtifactStagingDirectory)\MyApp-Win-x64-v$(version).zip"'

However the above script doesn't work either, as if we don't have permission to change that zip file, no matter what I cannot rename it.

Fixed - Solution

I had to move the rename power shell script to before Publish Artifact


- task: PowerShell@2
  inputs:
    targetType: 'inline'
    script: |
         $xml = [Xml] (Get-Content .\MyApp\MyApp.csproj)
         $version = $xml.Project.PropertyGroup.Version
         echo $version
         echo "##vso[task.setvariable variable=version]$version"

- task: DotNetCoreCLI@2
  inputs:
    command: 'publish'
    publishWebProjects: false
    projects: '**/MyApp.csproj'
    arguments: '-r win-x64 -p:PublishSingleFile=True --self-contained true -o $(Build.ArtifactStagingDirectory)'

- task: PowerShell@2
  inputs:
    targetType: 'inline'
    script: 'Rename-Item -Path "$(Build.ArtifactStagingDirectory)\MyApp.zip" -NewName "$(Build.ArtifactStagingDirectory)\MyApp-Win-x64-v$(version).zip"'


- task: PublishBuildArtifacts@1
  displayName: 'Publish Artifact'
  inputs:
    PathtoPublish: '$(build.artifactstagingdirectory)'
  condition: succeededOrFailed()
  


Solution

  • To set the name of the output file(zip file), you need to set the corresponding format in dotnet build argument.

    --configuration $(BuildConfiguration) --output $(build.artifactstagingdirectory)/MyApp-$(version)
    

    In order to get the Version value in csproj file, you can add a powershell task before the Dotnet Publish task. Then you could retrieve project version from csproj

    Here is my example:

    - powershell: |
       $xml = [Xml] (Get-Content .\MyApp.csproj)
       $version = $xml.Project.PropertyGroup.Version
       
       echo $version
       
       echo "##vso[task.setvariable variable=version]$version"
      displayName: 'PowerShell Script'
    
    - task: DotNetCoreCLI@2
      displayName: Publish
      inputs:
        command: publish
        publishWebProjects: false
        projects: '**/*.csproj'
        arguments: '--configuration $(BuildConfiguration) --output $(build.artifactstagingdirectory)/MyApp-$(version)'
    
    - task: PublishBuildArtifacts@1
      displayName: 'Publish Artifact'
      inputs:
        PathtoPublish: '$(build.artifactstagingdirectory)'
      condition: succeededOrFailed()
    

    Result:

    enter image description here

    You can also try to set the name as $(build.artifactstagingdirectory)/MyApp-v$(version)

    The output name will be MyApp-v1.0.0.zip

    Update:

    I have tested your sample in Yaml Pipeline and I could reproduce this issue.

    To solve this issue, you could add the parameter: modifyOutputPath: false in Dotnet Publish task.

    Here is the yaml sample:

    - task: PowerShell@2
      inputs:
        targetType: 'inline'
        script: |
             $xml = [Xml] (Get-Content .\MyApp\MyApp.csproj)
             $version = $xml.Project.PropertyGroup.Version
             echo $version
             echo "##vso[task.setvariable variable=version]$version"
    
    
    - task: DotNetCoreCLI@2
      displayName: Publish
      inputs:
        command: publish
        publishWebProjects: false
        projects: '**/*.csproj'
        arguments: '--configuration $(BuildConfiguration) --output $(build.artifactstagingdirectory)/MyApp-v$(version)'
        modifyOutputPath: false
    
    
    
    - task: PublishBuildArtifacts@1
      displayName: 'Publish Artifact'
      inputs:
        PathtoPublish: '$(build.artifactstagingdirectory)'
      condition: succeededOrFailed()