Developing NuGet packages without pushing to NuGet server - c#

I have 2 solutions in VS.
The first one is for packages.
Packages.sln
- PackageA
- PackageB
- Package..
Each packages has <GeneratePackageOnBuild>true</GeneratePackageOnBuild> to generate Package.nupkg.
And solution with services where I'm going to use that packages
Services.sln
- ServiceA
- ServiceB
- Service..
The question is how can I during development change package and use it in service?
I've tried this:
Create Local NuGet source in some folder "artifacts"
Each package has it in .csproj
:
<Target Name="PostBuild" AfterTargets="GenerateNuspec" Condition="$(Configuration) == 'Debug' ">
<Exec Command="nuget.exe push bin\Debug\*.nupkg -Source "Local Package source"" />
</Target>
Then I need to change version of package, let's say <VersionPrefix>1.0.1</VersionPrefix>
Then in service change to <PackageReference Include="PackageA" Version="1.0.*" />
So, make change in package, build, remove package from nugget cache, rebuild service, test, if ok then commit and CI will push it to nuget server. There are many steps to test package. Please suggest what workflow should I use when I develop packages and want to test it before pushing to Nuget server.

Related

Nuget PackageReference found in one solution, but not in my own solution

Previous title:
The "GenerateFileFromTemplate" task was not found
.NET project template - GeneratedContent
.csproj.in file transformations
The troubled package is Microsoft.DotNet.Build.Tasks.Templating.
I've created a git-repository containing multiple .NET project templates. When opened in Visual Studio, VS had a horrible performance when adding more files to the template project. This turned out to be caused by my template's project files having .csproj extension. Therefor I've changed the extensions of all my template csproj files to csproj.in.
Because of this, I need to add a msbuild task that transforms this .csproj.in to .csproj. There are several examples out on the internet:
ASP.NET Core project templates
spa-templates (Seems to use the Arcade SDK)
dotnet-template-samples (very basic)
microsoft/SEAL
In the above samples, there is no nuget.config in the project.
Your root csproj file contains a <GeneratedContentProperties> and <GeneratedContent> section:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<GeneratedContentProperties>
DefaultNetCoreTargetFramework=$(DefaultNetCoreTargetFramework);
</GeneratedContentProperties>
</PropertyGroup>
<ItemGroup>
<GeneratedContent Include="Angular-CSharp.csproj.in" OutputPath="content/Angular-CSharp/Company.WebApplication1.csproj" />
<GeneratedContent Include="React-CSharp.csproj.in" OutputPath="content/React-CSharp/Company.WebApplication1.csproj" />
</ItemGroup>
</Project>
The .csproj.in files reference the GeneratedContentProperties:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>${DefaultNetCoreTargetFramework}</TargetFramework>
...
</PropertyGroup>
...
</Project>
I've tried applying the same files to my project in this commit, but I'm still getting the following error when building the project:
dotnet build --configuration Release
MSBuild version 17.3.0+92e077650 for .NET
Determining projects to restore...
C:\Program Files\dotnet\sdk\6.0.400\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.DefaultItems.Shared.targets(152,5): warning NETSDK1023: A PackageReference for 'Microsoft.DotNet.Build.Tasks.Templating' was included in your project. This package is implicitly referenced by the .NET SDK and you do not typically need to reference it from your project. For more information, see https://aka.ms/sdkimplicitrefs [C:\repos\MintPlayer.AspNetCore.Templates\MintPlayer.AspNetCore.
IdentityServer.Templates\MintPlayer.AspNetCore.IdentityServer.Templates.csproj]
...
All projects are up-to-date for restore.
...
C:\repos\MintPlayer.AspNetCore.Templates\eng\GenerateContent.targets(27,3): error MSB4036: The "GenerateFileFromTemplate" task was not found. Check the following:
1.) The name of the task in the project file is the same as the name of the task class.
2.) The task class is "public" and implements the Microsoft.Build.Framework.ITask interface.
3.) The task is correctly declared with <UsingTask> in the project file, or in the *.tasks files located in the "C:\Program Files\dotnet\sdk\6.0.400" directory
[C:\repos\MintPlayer.AspNetCore.Templates\MintPlayer.AspNetCore.IdentityServer.Templates\MintPlayer.AspNetCore.IdentityServer.Templates.csproj]
Build FAILED.
It seems that dotnet cannot find the GenerateFileFromTemplate Task...
I also see that the spa-templates project is using the Arcade SDK, but I don't think I'd actually need that...
How can I fix this? What am I still missing here?
EDIT
When I open both projects in Visual Studio, this is what I see:
Nuget packages for my template project:
C:\repos\MintPlayer.AspNetCore.Templates\MintPlayer.AspNetCore.IdentityServer.Templates> dotnet restore
Determining projects to restore...C:\repos\MintPlayer.AspNetCore.Templates\MintPlayer.AspNetCore.IdentityServer.Templates\MintPlayer.AspNetCore.IdentityServer.Templates.csproj : warning NU1604: Project dependency Microsoft.DotNet.Build.Tasks.Templating does not contain an inclusive lower bound.
Include a lower bound in the dependency version to ensure consistent restore results.
C:\repos\MintPlayer.AspNetCore.Templates\MintPlayer.AspNetCore.IdentityServer.Templates\MintPlayer.AspNetCore.IdentityServer.Templates.csproj : error NU1101: Unable to find package Microsoft.DotNet.Build.Tasks.Templating. No packages exist with this id in source(s): C:\Program Files\dotnet\library-packs, Local, Microsoft Visual Studio Offline Packages, nuget.org
Failed to restore C:\repos\MintPlayer.AspNetCore.Templates\MintPlayer.AspNetCore.IdentityServer.Templates\MintPlayer.AspNetCore.IdentityServer.Templates.csproj (in 516 ms).
Nuget packages for spa-templates:
C:\repos\spa-templates\src> dotnet restore
Determining projects to restore...
C:\repos\spa-templates\src\Microsoft.DotNet.Web.Spa.ProjectTemplates.csproj : warning NU1603: Microsoft.DotNet.Web.Spa.ProjectTemplates.7.0 depends on Microsoft.DotNet.Build.Tasks.Templating (>= 6.0.0-beta.21373.11) but Microsoft.DotNet.Build.Tasks.Templating 6.0.0-beta.21373.11 was not found. An approximate best match of Microsoft.DotNet.Build.Tasks.Templating 6.0.0-beta.22212.5 was resolved.
All projects are up-to-date for restore.
So it seems that dotnet restore is unable to restore this package. However, the nuget sources are the same for both projects:
IdentityServer.Templates>dotnet nuget list source
Registered Sources:
1. nuget.org [Enabled]
https://api.nuget.org/v3/index.json
2. Local [Enabled]
C:\packages
3. Microsoft Visual Studio Offline Packages [Enabled]
C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\
C:\repos\spa-templates>dotnet nuget list source
Registered Sources:
1. nuget.org [Enabled]
https://api.nuget.org/v3/index.json
2. Local [Enabled]
C:\packages
3. Microsoft Visual Studio Offline Packages [Enabled]
C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\
EDIT 2
Hmm, it seems that GenerateFileFromTemplate is part of the Arcade SDK... (Howto)
How to install Microsoft.DotNet.Arcade.Sdk into the dotnet sdk folder?
It seems that the package is only available through the following NuGet feed:
https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json
So I added a nuget.config in the root of the project/repository:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="dotnet-eng" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json" />
</packageSources>
</configuration>
And since there's only preview versions of the package, you need for example the following version (eng/Versions.props):
<Project>
...
<PropertyGroup Label="Package versions">
<MicrosoftDotNetBuildTasksTemplatingVersion>6.0.0-beta.21373.11</MicrosoftDotNetBuildTasksTemplatingVersion>
...
</PropertyGroup>
</Project>

Nuget package installed but cannot be imported

I am trying to add a nuget package "Azure.ResourceManager" to an existing project.
Here is the .csproj file:-
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="Azure.Identity" Version="1.6.0" />
<PackageReference Include="Azure.ResourceManager" Version="1.0.0" />
<PackageReference Include="Azure.ResourceManager.Resources" Version="1.0.0" />
....
</ItemGroup>
</Project>
I ran the nuget restore command on the solution, and I have checked that the package is installed through the Visual Studio Package Manager Console, using command
PM> Find-Package ResourceManager
Id Versions Descriptio
n
-- -------- ----------
Azure.ResourceManager {1.0.0} Azure m...
Azure.ResourceManager.Communication {1.0.0} Azure m...
Azure.ResourceManager.Deployment... {1.0.111} This pr...
Azure.ResourceManager.Deployment... {1.0.111} This pa...
However, when I try to import this package into a class, the type cannot be resolved.
I wondered if the package and project targeted different versions, so I checked.
Target frameworks supported by package
Target framework supported by project
In summary,
As far as I can tell, both project and package support .Net Core 3.1 as a target framework.
Package is installed into project, but cannot be imported into class
Another thing I noticed is that the type "ResourceManager" is being searched for in the "Microsoft.Azure" namespace instead of "Azure"
Looking for any pointers to resolve the issue.
I learnt that the issue was happening because of naming conflicts within the namespace that I was trying to add the import in. There seems to have been another namespace "Azure." within the one I was adding code to. Adding a glocal prefix helped resolve the issue.
using global::Azure.ResourceManager;
This seems like a bug. I just created a solution with a .NET core 3.1 project inside. I used the Nuget Manager ui and it worked fine. Have you tried installing it that way?

Issue with Nuget package versions in .NET Core

Net core application. I have created some class library project named Authorization and it has reference to
<PackageReference Include="Microsoft.Identity.Web" Version="1.10.0" />
Then I have another class library project and I have reference to
<PackageReference Include="Azure.Identity" Version="1.2.3" />
Both these class library applications I have pushed to azure artifact and I am using it in current application. when I try to build the solution Its giving me below error
RepositoryLayer.csproj :
error NU1605: Detected package downgrade: Azure.Identity from 1.3.0 to 1.2.3. Reference the package directly from the project to select a different version.
RepositoryLayer.csproj :
error NU1605: RepositoryLayer -> Consume 1.1.46955 -> HttpClients 1.1.46955 ->
Authorisation 1.1.46955 -> Microsoft.Identity.Web 1.10.0 -> Azure.Identity (>= 1.3.0)
RepositoryLayer.csproj :
error NU1605: RepositoryLayer -> Azure.Identity (>= 1.2.3)
already spent hours to identify this but could not able to understand the root cause. Can someone help me to identify this issue. Any help would be appreciated. Thanks
3 steps:
(1) Use latest version
https://www.nuget.org/packages/Azure.Identity (1.4.0)
https://www.nuget.org/packages/Microsoft.Identity.Web (1.12.0)
(You should use .NET 5 SDK 5.0.6 with Azure.Identity 1.4.0 and Microsoft.Identity.Web 1.12.0 for ensuring compatibible)
(2) Clean Nuget cache, then get nuget package again.
https://learn.microsoft.com/en-us/nuget/consume-packages/managing-the-global-packages-and-cache-folders#clearing-local-folders
You can/should delete all old thing inside the folder packages for clear all old stuff. I want make sure no corrupt files existing.
(3) Delete bin, obj, re-build project.
Let's share your result.

Custom .NET Standard Nuget package not installing correctly

I have a .NET Standard class library project with a number of POCO's. This project is built using TeamCity and published as a Nuget package using the built-in Nuget server.
The problem I'm having is when it's installed into my solution with a number of .NET Framework class library projects and ASP.NET MVC and Web API projects (set to .NET Framework 4.7.1), it seems to be stuck on an older version and is not recognising any new classes or methods I add to the project - e.g. NewMethod1()
Project File for Nuget package
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net461;net462;net47</TargetFrameworks>
<Version>1.0.0</Version>
</PropertyGroup>
<PropertyGroup>
<NetStandardImplicitPackageVersion>2.0.0</NetStandardImplicitPackageVersion>
<Description>Standard entities used within our systems</Description>
<AssemblyVersion>1.0.0.0</AssemblyVersion>
<FileVersion>1.0.0.0</FileVersion>
<Authors>Company X</Authors>
<Company>Company X</Company>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<OutputPath>bin\Release</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>bin\Debug</OutputPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
</ItemGroup>
</Project>
TeamCity is using the 'dotnet' restore, build & pack options.
The package is stored in my Nuget cache located in C:\Users\antho.nuget\packages. When I use Object Browser to inspect the dll, it contains the new classes and methods (e.g. NewMethod1()).
When I install this package into my .NET Framework solution, no errors occur during the installation. If I try and use the new method - NewMethod1() - the code doesn't compile.
If I create a brand new solution and ASP.NET MVC project and install the package, the new method can be used in code and it compiles successfully.
What could be causing the new version not to be installed correctly? It's tricky to provide a sample reproducing the issue because it seems to work in a new project.
Update
If I add a new project to the solution and install the Nuget package, it gets the latest version.
Project A
<PackageReference Include="AutoGuru.Shared.Utilities" Version="1.0.369" />
public class Class1
{
public void Test()
{
"dfdfdfdf".SanitizeVehicleRego();
}
}
Project B
<PackageReference Include="AutoGuru.Shared.Utilities">
<Version>1.0.369</Version>
</PackageReference>
public class Class1
{
public void Test()
{
"fdfdf".SanitizeVehicleRego();
}
}
Project B compiles successfully and Project A doesn't. SanitizeVehicleRego() is a string extension method in the AutoGuru.Shared.Utilities package.
My answer it quite big, so I add an answer instead of comment.
Step 1
Check the output when you restore the package, sometimes dotnet restore resolve an other version automatically ( you should have a warning for this kind of things in your console ).
Step 2
If any information was found in Step 1. Try to clean all your local nuget cache.
dotnet nuget locals all --clear
I'm not sure if local nuget packages are under cache stategy. But if they are, it should resolve the correct version of your package.

C#/.NET - How to generate and increase package version automatically especially via CI?

I have a Visual Studio project which is built as a NuGet lib package. But every time I publish the package, I have to change the version number manually. That's a prone-to-error work.
I'd like to generate and increase the package version number automatically.
I found GitVersion tool to solve this problem. And I also found some semantic versioning blogs to explain the package version of continuous delivery.
GitTools/GitVersion: Easy Semantic Versioning (http://semver.org) for projects using Git
GitVersion Documentation
Versioning NuGet packages in a continuous delivery world: part 1 – Microsoft DevOps Blog
Versioning NuGet packages in a continuous delivery world: part 2 – Microsoft DevOps Blog
Versioning NuGet packages in a continuous delivery world: part 3 – Microsoft DevOps Blog
But unfortunately, The GitVersion package does not work correctly for me.
It gives me an error that AssemblyVersionAttribute is duplicated.
If I add <GenerateAssemblyInfo>false</GenerateAssemblyInfo> into the csproj file, It will do nothing and the package version will be 0.0.0.0.
Maybe the reason is that I'm using the new csproj format. See here to view the csproj file and the file looks like this:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net45;net47;netstandard2.0</TargetFrameworks>
</PropertyGroup>
</Project>
Any reply is appreciated.
UPDATE:
I find that there is an issue to mention my problem: Gitversion Task for VS2017-style csproj · Issue #1349 · GitTools/GitVersion. I'm trying the new solution.
Not sure about Jenkins, but it should be able to generate an incremental number or timestamp by itself that can be accessed via an environment variable on your build pipeline.
I think the most flexible way is to add a PackageVersion tag with a placeholder to your csproj that your build pipeline can then change:
<PropertyGroup>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<PackageVersion>$(PackageVersion)</PackageVersion>
</PropertyGroup>
So, on your build pipeline, you just pass the version, for example:
dotnet build -p:PackageVersion=$(BUILD_TIMESTAMP)
We can trigger the GitHub Action by Git tag pushed and we can read the Git tag name as the version. And then we can generate the NuGet package with this version.
There is a dotnet tool that can read Git tags as a version and write it to the version file.
Before using it, we should create the version file and import the version file.
We should use dotnet to install the dotnetCampus.TagToVersion tool and use the tool to write the Git tag to version file.
The step 1:
Adding the Directory.Build.props file to repo folder.
Writing the code to the Directory.Build.props file.
<Project>
<Import Project="build\Version.props" />
</Project>
The step 2:
Making a folder named build and adding the Version.props file to this folder.
Writing the code to the build\Version.props file.
<Project>
<PropertyGroup>
<Version>1.0.5</Version>
</PropertyGroup>
</Project>
The step 3:
Writing a GitHub Action configuration file in .github\workflows folder, for example create the .github\workflows\push tag and pack nuget.yml file
Making the Action trigger by tag push.
on:
push:
tags:
- '*'
Writing the tag as version by dotnet tool.
- name: Install dotnet tool
run: dotnet tool install -g dotnetCampus.TagToVersion
- name: Set tag to version
run: dotnet TagToVersion -t ${{ github.ref }}
Building the package
# Build and publish
- name: Build with dotnet
run: dotnet build --configuration Release
- name: Install Nuget
uses: nuget/setup-nuget#v1
with:
nuget-version: '5.x'
- name: Add private GitHub registry to NuGet
run: |
nuget sources add -name github -Source https://nuget.pkg.github.com/ORGANIZATION_NAME/index.json -Username ORGANIZATION_NAME -Password ${{ secrets.GITHUB_TOKEN }}
- name: Push generated package to GitHub registry
run: |
nuget push .\bin\release\*.nupkg -Source github -SkipDuplicate
nuget push .\bin\release\*.nupkg -Source https://api.nuget.org/v3/index.json -SkipDuplicate -ApiKey ${{ secrets.NugetKey }} -NoSymbols
See https://github.com/dotnet-campus/dotnetCampus.TagToVersion
Actually GitVersionTask is not hard to use. All that you should do is these things below:
Install GitVersionTask from NuGet.
Add a configuration file named GitVersion.yml with some key-values.
Add a tag to your branch.
Build.
After doing that, you can find your output dll file contains a semantic version.
I'm answering my own question because I just wrote the wrong config file name. So it did not work correctly.
This is my configuration file:
mode: ContinuousDelivery
increment: Inherit
tag-prefix: '[vV]'
source-branches: ['master', 'develop', 'hotfix']
branches:
master:
regex: master$
mode: ContinuousDelivery
tag: ''
increment: Patch
prevent-increment-of-merged-branch-version: true
track-merge-target: false
tracks-release-branches: false
is-release-branch: true
release:
regex: r(elease$|(eleases)?[-/])
mode: ContinuousDelivery
tag: beta
increment: Patch
prevent-increment-of-merged-branch-version: true
track-merge-target: false
tracks-release-branches: false
is-release-branch: true
feature:
regex: f(eatures)?[-/]
mode: ContinuousDeployment
tag: alpha
increment: Minor
prevent-increment-of-merged-branch-version: false
track-merge-target: false
tracks-release-branches: false
is-release-branch: false
I've posted this configuration file content here: Automatically increase the semantic version using GitVersion - walterlv

Categories