dotnet pack multiple projects into one package - nuget-package

I have a build pipeline that is building multiple library files in a single solution. In the YML file I have the following task to package the dlls;
- task: DotNetCoreCLI#2
displayName: 'Create nuget packages'
inputs:
command: 'pack'
packagesToPack: 'Framework/**/*.csproj;!**/*.Test.csproj'
packDirectory: '$(Build.ArtifactStagingDirectory)/packages/nuget'
nobuild: true
versioningScheme: 'byBuildNumber'
This creates all my library files as seperate nupkg files. I would like them in one nupkg file.
Is this possible using dotnet pack?

One of the way of doing that is to create a nuspec that includes outputs of the csproj you want to bundle since the pack command only accepts a single project.
You can also use the dependencies attribute to link to other nupkg instead of bundling them.

Related

DotNetCoreCLI restore vs NuGetCommand restore

I am trying to understand the difference between the two nuget restore commands in Azure build pipeline:
- task: NuGetCommand#2
inputs:
restoreSolution: '$(solution)'
and
- task: DotNetCoreCLI#2
inputs:
command: 'restore'
projects: '$(solution)'
feedsToUse: 'select'
I have tried to understand but at microsoft pages all I see is that one can use both - I can't really find anything stating what the differences are. (I do not really understand the feedsToUse: 'select' statement either)
And, as a second question, what is the difference between the latter and
- task: DotNetCoreCLI#2
inputs:
command: restore
projects: '**/*.csproj'
Given that the solution contains all of the csproj (and only csproj)?
Nuget task is used to install and update NuGet package dependencies, or package and publish NuGet packages. Uses NuGet.exe and works with .NET Framework apps. For .NET Core and .NET Standard apps, use the .NET Core task.
dotnet restore internally uses a version of NuGet.exe that is packaged with the .NET Core SDK. dotnet restore can only restore packages specified in the .NET Core project .csproj files. If you also have a Microsoft .NET Framework project in your solution or use package.json to specify your dependencies, you must also use the NuGet task to restore those dependencies.
In .NET Core SDK version 2.0 and newer, packages are restored automatically when running other commands such as dotnet build. However, you might still need to use the .NET Core task to restore packages if you use an authenticated feed.
Regarding feedsToUse: 'select', when the packages cached in Azure Artifacts with upstream sources, you should use feedsToUse: 'select', and specify vstsFeed: xxxx. Check the following syntax (If you want to restore packages from an external custom feed, use feedsToUse: 'config', and specify nugetConfigPath and externalFeedCredentials):
#feedsToUse: # Options: select, config
#vstsFeed: # Required when feedsToUse == Select
#nugetConfigPath: # Required when feedsToUse == Config
#externalFeedCredentials: # Optional
When you don't need packages cached in Azure Artifacts, or from an external custom feed, use the following syntax (You should specify the path to the csproj file(s) to use in projects, not the path to the solution):
- task: DotNetCoreCLI#2
displayName: 'dotnet restore'
inputs:
command: restore
projects: '**/*.csproj'
Useful links:
https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/package/nuget?view=azure-devops
https://learn.microsoft.com/en-us/azure/devops/pipelines/ecosystems/dotnet-core?view=azure-devops&tabs=dotnetfive

How to compile .NET (console application) in Azure DevOps and generate an exe

I created a pipeline using the .NET desktop template and using the 'create .msi' extension but it shows a warning:
##[warning]No .MSI files were found, please check your build-configuration. If this is expected, you might consider to use the default Visual Studio Build task instead of this custom Installer task.
2018-11-28T22:58:54.1434410Z ##[section]Finishing: Create .msi file(s) from VS Installer project(s).
Anyone know how can I achieve creating an exe file using an Azure Pipeline and deploy it on a Virtual Machine.
If you use .NET Core CLI task to build your console app.
Below dotnet publish arguements commmand will generate .exe file. See this thread for more information.
dotnet publish -r win-x64 -p:PublishSingleFile=True --self-contained false
So you can add above arguments to your .NET Core CLI task. See below yaml pipeline.
- task: DotNetCoreCLI#2
inputs:
command: publish
arguments: -r win-x64 -p:PublishSingleFile=True --self-contained false -o $(Build.ArtifactStagingDirectory)
projects: '**/*.csproj'
publishWebProjects: false
enabled: true
Above DotNetCoreCLI task will output the .exe file to folder $(Build.ArtifactStagingDirectory) (ie. C:\agent\_work\1\a)
If you use Visual Studio Build task to build your console app.
You can first add below <PublishSingleFile> and <RuntimeIdentifier> properties to the .csproj file of your project.
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<PublishSingleFile>True</PublishSingleFile>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
</PropertyGroup>
Then set the msbuildArgs of the Visual Studio Build task in your pipeline as below:
- task: VSBuild#1
inputs:
solution: '$(solution)'
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
msbuildArgs: '/t:publish /p:PublishSingleFile=True /p:RuntimeIdentifier=win-x64 /p:outputpath=$(Build.ArtifactStagingDirectory)\'
Then Vsbuild task will output the .exe file to folder $(Build.ArtifactStagingDirectory) specified in /p:outputpath (ie. C:\agent\_work\1\a)

Trigger a specific project inside a repository when creating a build in Azure build pipeline

I have one repository with 3 branches dev, test and prod. I have a Visual Studio solution with 3 projects in it. One Angular, a worker service and ASP.NET web api project. So that whole solution in one repository.
I have pushed everything to dev branch. So when creating the build pipeline I chose ASP.NET core and then on writing the build yaml, in the trigger I specified Dev branch
trigger : - dev
But how can I specify which project to build among the 3 project in that repository to build? My plan is to build the ASP.NET core web api to build.
Also I need another build for the angular as well..
This will be in your build task:
steps:
- task: DotNetCoreCLI#2
displayName: Build
inputs:
command: build
projects: '**/*.csproj' # Update this to match your need
arguments: '--configuration $(buildConfiguration)'
The project path will be different for your various projects

How to pass azure pipelines dotnet inputs to the linux dotnet binary

I am trying to replicate the following Azure pipeline using the CLI dotnet command:
- task: DotNetCoreCLI#2
inputs:
command: publish
publishWebProjects: True
arguments: '--configuration Release --output $(Build.ArtifactStagingDirectory)'
zipAfterPublish: True
So far, I can make the project build, but getting a zip file out of it seems problematic - passing the inputs zipAfterPublish etc appears impossible to pass, although, there is some scattered documentation suggesting these can be passed with -p:"optiona=x;optionb=y" or /p:"optiona=x;optionb=y". I can find no definitive documentation on this.
This is what I have - the build part works, the $PWD/out directory is populated with many files but nothing is zipped:
dotnet publish --configuration Release --output $PWD/out /p:"zipAfterPublish=true;publishWebProjects=true"
I'm guessing this is around how to pass the inputs ( https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/build/dotnet-core-cli?view=azure-devops ) correctly to the command.
I am trying to replicate the following Azure pipeline using the CLI
dotnet command:
1.The zipAfterPublish is one option available only in Dotnet Publish task. If you check the log of dotnet publish task, you'll find it doesn't pass any property like zipAfterPublish to the command:
Since only the msbuild property can be passed in this way: /p:xxx=xxx. The zipAfterPublish won't work in command-line as it's not msbuild property, that option is not supported in dotnet cli, only available in Azure Devops Dotnet Publish task.
2.Normally if we want to publish one .net core web project and zip it after publish using dotnet cli locally, we can use command like:
dotnet publish xx.csproj /nologo /p:PublishProfile=xxx /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /maxcpucount:1 /p:platform=xxx /p:configuration=xxx /p:DesktopBuildPackageLocation=SomePath\xxx.zip
Or
dotnet build xxx.sln /nologo /p:PublishProfile=Release /p:PackageLocation="C:\Some\Path\package" /p:OutDir="C:\Some\Path\out" /p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /maxcpucount:1 /p:platform="Any CPU" /p:configuration="Release" /p:DesktopBuildPackageLocation="C:\Some\Path\package\package.zip"
Which is described in this issue.
Above commands can work in windows to generate a xx.zip folder.
However:
It seems that you're in linux environment, please check this document. If you want to zip the publish folder(generate a package), the dotnet build/publish will call msdeploy.exe to do this job, but since MSDeploy lacks cross-platform support, the following MSDeploy options are supported only on Windows. So dotnet cli command is not supported to generate zip after publish in linux environment... What you want is not supported for now in Linux.
Possible workaround:
Since we can use dotnet publish to publish the project to one folder(Folder works cross-platform), we can call another zip command after dotnet publish to zip it ourselves.
Hope my answer helps to resolve your puzzle :)

Ensuring azure pipeline built dll and nuget package contain same info as csproj version

I am reposting with a specific question as i have understand a powershell script is requried in addition to azure-pipelines.yml.
How would i achieve the same output/formatting using azure pipelines to provide the following versioning in an output file (and matching nuget package info per https://www.nuget.org/packages/MediatR/).
I understand this would be a powershell script, i have checked on MediatR and see https://github.com/jbogard/MediatR/blob/master/Build.ps1 but can't see how i would apply that to an azure pipeline step.
In summary the the verisn prefix should be used <VersionPrefix>1.0.1</VersionPrefix> (or whatever the version is) from my csproj, and applied to the file version property both in the binary dll and nuget package.
I would also like to set the product version of the dll to the specific build-datetime (or commit string as has been used in case of MediatR).
I am specifically looking for a script (powershell and associated yaml to link the scripted version strings) and associated steps, appreciate a big ask however I cannot find any concrete answers on google or Stackorerflow - a link to a tutorial would be perfect.
Pointers appreciated.
In summary the the verisn prefix should be used
1.0.1 (or whatever the version is) from
my csproj, and applied to the file version property both in the binary
dll and nuget package.
I would also like to set the product version of the dll to the
specific build-datetime (or commit string as has been used in case of
MediatR).
Apart from the PowerShell direction, we may consider msbuild property as another direction.
This is my test.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<!--Add other properties here.-->
</PropertyGroup>
<PropertyGroup> <!--Custom Property Group for CI/CD-->
<MyVersionPrefix>1.0.1</MyVersionPrefix>
<MyVersionSuffix>0</MyVersionSuffix>
<BuildDateTime>0</BuildDateTime>
<AssemblyVersion>$(MyVersionPrefix).$(MyVersionSuffix)</AssemblyVersion> <!--File Version-->
<Version>$(MyVersionPrefix).$(BuildDateTime)</Version> <!--Product Version-->
<PackageVersion>$(MyVersionPrefix).$(MyVersionSuffix)</PackageVersion> <!--Nuget Package Version-->
<Copyright>Just for test.</Copyright>
</PropertyGroup>
</Project>
I have one custom Property Group to define properties like File Version, Product Version and Package Version. Instead of using <VersionPrefix>1.0.1</VersionPrefix>, I use custom <MyVersionPrefix>1.0.1</MyVersionPrefix>.
This can work well to restore,build in local development. If you also need to pack the project locally, you can comment(using <---->) this Property Group.
To configure this project with CI/CD:
My opinion is to override the properties defined in xx.csproj. For me, I created one Suffix pipeline variable:
And then set the pipeline build number format to: $(date:yyyyMMdd)$(rev:r).
Then I specify the dotnet build task and dotnet pack task like this:
- task: DotNetCoreCLI#2
displayName: "Build Solution"
inputs:
command: build
projects: '**/*.csproj'
arguments: '--configuration $(BuildConfiguration) -p:MyVersionSuffix=$(Suffix) -p:BuildDateTime=$(Build.BuildNumber)'
- task: DotNetCoreCLI#2
displayName: 'dotnet pack'
inputs:
command: pack
nobuild: true
buildProperties: 'MyVersionSuffix=$(Suffix)'
In this way, I can pass value of $(Suffix) and $(Build.BuildNumber) from build pipeline to msbuild command. I can control the file version, product version, nuget package version by pipeline variables. (About the corresponding property of the file,product,package versions see my project file above.)
If set the Suffix variable 19, then after the build and package I can get a Nuget package whose package version is 1.0.1.19. In which the assembly has same file version 1.0.1.19 and product version like 1.0.1.202001208. If you don't want one increasing product version, you can then specify the value you want in build task with: -p:BuildDateTime=AnyValueYouWant.
Hope it helps and if I misunderstand anything, feel free to correct me :)

Resources