AzureDevOps/VSTS Build - Could not find version number data in BUILD_BUILDNUMBER - azure-devops

Setting up a simple class library to build and publish to VSTS's own feed, I see this error when the NuGet package runs.
Could not find version number data in BUILD_BUILDNUMBER
I have the "Use Build number to version package" option ticked. Expected VSTS to just work.

The tip for "Use Build number to version package" states:
Will use the build number to version you package. Under General set the build format to be '$(BuildDefinitionName)_$(Year:yyyy).$(Month).$(DayOfMonth)$(Rev:.r)'
Following this did get me past this issue (and on to a new one).
Default value:
[]
Correct Value:
[]

This is because your build number does not match the regex in "Nuget Packager" step. Following is the regex that nuget packager task used to find the build number. You can set your build number format base on this. General, the format like 1.2.3 or 1.2.3.4 would work.
Write-Verbose "Autoversion: Getting version number from build"
##Get Version from Build
# Regular expression pattern to find the version in the build number
# and then apply it to the assemblies
$VersionRegex = "\d+\.\d+\.\d+(?:\.\d+)?"

If what you want is the major.minor.patch.unique-to-build then you use the Use the date and time option.
In yaml, the equivalent is
- task: NuGetCommand#2
displayName: Pack
inputs:
command: 'pack'
packagesToPack: '**/*.csproj'
versioningScheme: 'byPrereleaseNumber'
majorVersion: '1'
minorVersion: '0'
patchVersion: '0'

I had a variable in my .nuspec file:
<tags>Build#$build$</tags>
that was incorrectly parameterized in the package build step. With the package step open in the build editor, I expanded the 'Advanced' section added to 'Additional Build Properties' this text
build=$(Build.BuildNumber)

Related

DotNetCoreCLI#2 / pack in Azure DevOps pipeline is looking for files in the wrong subfolder

TL;DR
I'm building a nuget package with Azure Devops pipelines, and the DotNetCoreCLI#2 / pack command is looking for the built assemblies and other files of dependent projects in the wrong folder because the name of the solution configuration the yaml uses is different from the name of the build configuration of the dependent projects the solution configuration uses.
In detail:
The project dependencies in the solution: Main --> DepA --> DepB.
The nuget package is built from Main.
The yaml uses a solution configuration called ReleaseMain, which ...
builds only the above projects
uses the Release build configuration of each project. I can't see any point in creating a separate build configuration called ReleaseMain in each project if Release can be referred to by ReleaseMain.
The relevant parts of the yaml:
variables:
buildConfiguration: 'ReleaseMain'
steps:
- task: NuGetToolInstaller#1
- task: DotNetCoreCLI#2
inputs:
command: 'restore'
projects: '**/Main.csproj'
feedsToUse: 'select'
vstsFeed: '<nuget feed ID>'
# I don't use a DotnetCoreCLI#2 / Build task because the pack command also builds everything it needs. This works with other pipelines.
- task: DotNetCoreCLI#2
inputs:
command: 'pack'
packagesToPack: '**/Main.csproj'
versioningScheme: 'off'
The pack task fails while building the DepB project because it is looking for obj\ReleaseMain\netstandard2.0\.NETStandard,Version=v2.0.AssemblyAttributes.cs but doesn't find it, since it is in the obj\Release\netstandard2.0\ folder. Then the log contains the same error for the DepA project, and the task fails.
So the problem is that the pack command is looking for release files in a subfolder named after the solution configuration instead of the build configuration of the projects.
In cases when the project from which the nuget package is built has no project dependencies, I can make the pipeline work by specifying the project build configuration name in the files/file XML elements of the nuspec file, see below.
<files>
<!-- instead of this -->
<file src="bin\$configuration$\netcoreapp3.1\Main.dll" target="lib\.NETCoreApp3.1" />
<!-- I hardcode this -->
<file src="bin\release\netcoreapp3.1\Main.dll" target="lib\.NETCoreApp3.1" />
</files>
But the build task is stuck before this step in the above scenario, so I only mention this as a side note.
There must be a solution for this because it seems a pretty frequent situation to me but I can't find it. I know I could create a project build configuration called ReleaseMain for each project but it seems unnecessary. Or is the way the nuget pack command works incompatible with this setup?

Set a variable from a NuGet list task in Azure DevOps pipeline

I'm building a pipeline to automate the publishing of NuGet Package on our private feed.
I'm trying to read the last version of a NuGet package, increment it and publish with the incremented value.
So far I found how to retrieve the list of all versions with this task:
- task: NuGetCommand#2
name: AllVersionList
inputs:
command: 'custom'
arguments: 'list HQTemplateMVC JSON -AllVersions -Source "https://prd-cvtfs01/DEVOPS/_packaging/HQ-Commun/nuget/v3/index.json"'
Now, I want to use the result of that task to parse the latest version. I don't find a way to get the output from the task.
I've tried $(AllVersionList.out) but it seems to be empty or non existant because if use "echo $(AllVersionList.out)" it print "$(AllVersionList.out)" instead of the value.
Anyone know a way to capture the output value from a NuGet task?
Thanks

Azure Function Build Pipelines Fails when Unit Test Project references the Function project

I am using Visual Studio 2019 Community Edition and I have a multi-tier solution. Below is a screenshot of that.
Please note, it's a sample project to replicate a production solution, so, namings probably are not really important here.
Project specifications: (all netcoreapp3.1)
Sample.AzureFunction.Api - Target Framework: netcoreapp3.1and Azure Function version: 3.0.7
{ Application, Model, ClassLibrary1, and ClassLibrary2 } - Target Framework: netcoreapp3.1 and all are `.netcore class library' projects.
ApiTests - Target Framework: netcoreapp3.1
The Problem
The Azure Build Pipeline fails when there is a reference from the ApiTest project to the Sample.AzureFunction.Api. If I remove the project reference, the build continues to be green. Here is a screenshot from the build errors when the build step is running in the pipeline.
Basically, all the errors are complaining about not finding some dlls. For example, CSC : error CS0006: Metadata file 'D:\a\1\s\publish_output\Application.dll' could not be found [D:\a\1\s\Sample.AzureFunction.Api\Tests\ApiTests\ApiTests.csproj]
Few Notes:
The build step in the pipeline is .net core added automatically by Azure DevOps.
I don't have a dedicated Agent and I use the Azure Pipelines that comes by default when creating a new CI.
Agent specification is windows-2019
I used the classic view to create the pipeline (no YAML) but I could grab the following YAML from the generated steps by clicking on each of them and copying the YAML:
I've spent a day on resolving this issue and I'm running out of ideas now. Any thoughts would be appreciated.
If you remove --output argument your build will succeeded.
It looks like your folder publish_output was cleared before compiling test project. Thus it can't find these dlls there.
Furthermore, you don't need rather to publish as an artifact all dlls. Please use publish command to create artifact for code which is going to be deployed:
- task: DotNetCoreCLI#2
inputs:
command: publish
publishWebProjects: True
arguments: '--configuration $(BuildConfiguration) --output $(Build.ArtifactStagingDirectory)'
zipAfterPublish: True
# this code takes all the files in $(Build.ArtifactStagingDirectory) and uploads them as an artifact of your build.
- task: PublishBuildArtifacts#1
inputs:
pathtoPublish: '$(Build.ArtifactStagingDirectory)'
artifactName: 'myWebsiteName'
I listed publish_output folder after running your original pipeline and you can find there these files:
Application.deps.json
ClassLibrary1.deps.json
Function1
Sample.AzureFunction.Api.deps.json
bin
host.json

DotNetCLI#2 pack seems to be ignoring configuration inputs

The below YAML snippet does not seem to work as expected.
I configured it in a pipeline that runs using the windows-latest image and it attempts to restore all of the projects that are in the repo, instead of looking just to the solution file.
Also, it seems to completely ignore the --no-restore flag
- task: DotNetCoreCLI#2
displayName: Package to Staging directory
inputs:
command: pack
configuration: $(BUILD_CONFIGURATION)
projects: 'support-libs.sln'
packDirectory: $(Build.ArtifactStagingDirectory)
nugetConfigPath: 'sf-solution/nuget.config'
arguments: '--no-restore'
verbosityRestore: Minimal
The command that appears on the step logs is:
"C:\Program Files\dotnet\dotnet.exe" pack
d:\a\1\s\sf-solution\SampleProject\SampleProject.csproj --output
d:\a\1\a /p:Configuration=Debug --verbosity Detailed
The above project is not even included in the support-libs SLN file the snippet has configured.
The above project is not even included in the support-libs SLN file the snippet has configured
Not sure why DotNetCLI task pack the project, which is not included in in the support-libs SLN. Since you did not share your project file structure and the build log in your question, I could not give you the directly reason for this issue.
But as workaround, you could specify the specific project file instead of the solution file. Besides, you can also check this task by classic editor:
It state the path to csproj or nuspec file(s) to pack.
For the ignoring configuration inputs problem, there is an option Do Not build, so, you could add this argument to your pack task instead of the argument --no-restore:
- task: DotNetCoreCLI#2
displayName: 'dotnet pack'
inputs:
command: pack
packagesToPack: YourProjectPath&Name.csproj
nobuild: true
Note: Add a DotNet build task before you use this pack task.
Hope this helps.
I was finally able to do what I wanted and to pack all the libraries inside the solution, however I had to use a custom command instead of the pack one:
- task: DotNetCoreCLI#2
displayName: Package to Staging directory
inputs:
command: custom
custom: 'pack'
arguments: 'support-libs.sln -c=$(BUILD_CONFIGURATION) -o $(Build.ArtifactStagingDirectory)'
verbosityRestore: Minimal
verbosityPack: Minimal
feedsToUse: select
vstsFeed: personalnugetfeed
nuGetFeedType: internal
includeNuGetOrg: true
I was also having authorization issues with the internal feed that was in the Nuget configuration and linking to that file, even from a custom command, had the same issues.
Explicitly stating from which feed the restore should be made worked perfectly and I was able to retrieve all the dependencies removing the need to use the --no-restore flag.

How to to produce both release and pre-release packages from one nuspec in VSTS?

Currently my build produces both packages having a newer version every time:
Release: Automatic package versioning = Use the build number
Pre-release: Additional build properties = Version=$(user.BuildFullVersion)-beta
And the only one nuspec has a placeholder to version:
<version>$version$</version>
I want to increment version manually, that it - repetitive build would produce same version until I increment it manually.
How can I achieve that still having single nuspec?
Can I adjust package version in the pack tasks like this:
Release: $(PackageVersion) = $(PackageVersion)
Pre-release: $(PackageVersion) = $(PackageVersion)-beta
Or something similar.
To produce two packages by a nuspec, you can use two NuGet tasks (NuGet custom instead NuGet pack):
NuGet task:
Command: custom
Command and arguments:
pack $(Build.SourcesDirectory)\Package.nuspec -Version $(Build.BuildNumber) -OutputDirectory $(build.artifactstagingdirectory)
NuGet task:
Command: custom
Command and arguments:
pack $(Build.SourcesDirectory)\Package.nuspec -Version $(Build.BuildNumber) -Suffix beta -OutputDirectory $(build.artifactstagingdirectory)
If you set the $(Build.BuildNumber) as the format like MyProject-Daily_1.0.94.0 while you want to add the version for nuget package as 1.0.94.0, you can define a variable in your build definition and set the value by cutting the substring of $(Build.BuildNumber). detail steps as below:
In Variables Tab, add a variable (such as version) with any value (such as temp).
Add a PowerShell Task before NuGet tasks with the settings,
Type: Inline Script
Inline Script:
$s1=$(Build.BuildNumber).split('_')[1].split(' ')
Write-Host "##vso[task.setvariable variable=version]$s1"
Then in the NuGet Custom tasks use $(version) to replace $(Build.BuildNumber) for -version option. Such as nuget pack -version $(version).