I was curious as to how you can run custom targets that were part of a NuGet package when building your project. e.g. when taking a dependancy on a package and building your project, the package you have taken a dependancy on will run some code during the build.
This project shows two ways this can be achieved - when running dotnet build
on the Testing.fsproj
the following happens:
Microsoft (R) Build Engine version 16.3.0+0f4c62fea for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.
Restore completed in 19.06 ms for C:\Users\Paul\source\repos\MSBuild.CustomTarget\Testing\Testing.fsproj.
Testing -> C:\Users\Paul\source\repos\MSBuild.CustomTarget\Testing\bin\Debug\netcoreapp3.0\Testing.dll
--------------------------------------------------------------------------------------------
You are now running a Target from a nuget package in your project. This target calls a Task.
Looked for Task source .dll at:
C:\Users\Paul\.nuget\packages\target.task\0.0.1\build\../lib/netstandard2.1/Target.Task.dll
A Target has sucessfully called a Task when building your project called 'Testing'
--------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------
You have run an Target excutable from a nuget package in your project 'Testing'
I will now print all your User Secrets:
The User Secret with Key: UpperKey:ServiceApiKey has a value of: 12345
The User Secret with Key: UpperKey:ConnectionString has a value of: MyConnString
--------------------------------------------------------------------------------------------
The full guide to MSBuild and some of the offical custom SDKs.
This is the most simple - see the Target.Task
project. One issue with this is that if you and any dependancies these .dlls
do not get packaged and the Task
will fail to run in the calling project.
This uses a netcoreapp3.0
that can be run using the exec
command - see the Target.Exec
project.
By using
<NuspecFile>Target.Exec.nuspec</NuspecFile>
and creating a custom .nuspec file allows this can be packed and then run and referenced from a netstandard2.1 project.
This project will read the User Secrets file if there is a <UserSecretsId>
property
<ItemGroup>
<SecretsKey Include="UpperKey:ServiceApiKey"/>
<SecretsKey Include="UpperKey:ConnectionString"/>
</ItemGroup>
In order to use a local version of the packages, use the RestoreSource
xml property in something like:
<RestoreSources>
https://api.nuget.org/v3/index.json;
../Target.Task/bin/$(Config);
../Target.Exec/bin/$(Config)
</RestoreSources>
If you package again and do not increment the package build it will not get replaced in the local NuGet store when running a restore: so you need to delete from C:/Users/User/.nuget
etc. NuGet cli reference.
// Show all sources
dotnet nuget locals all --list
// Clear all local cache
dotnet nuget locals all --clear
Having a folder named build
is the key to getting this to work. The project that is going to packed must have the following folder structure and naming convention:
MyProject.fsproj
./build
MyProject.props
MyProject.target
MyFiles.fs
Access a property with $(propName)
Access an item (list) with @(itemName)
. The item list can also be mapped in the form @(itemName -> Count())
.
See item functions.