I have a solution with many projects, when it's time to publish we usually go one by one and publish it on VS. This was consuming a lot of time so we tried to publish it via "dotnet.exe publish" and it was a massive improvement in publish times for each project.
This leaves me with some questions that the internet has been unable to answer me so far:
Is the command skipping any steps?
Are the published projects different in any way?
Why is it faster?
Here are both configurations I'm using:
VS Publish Profile:
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<LastUsedBuildConfiguration>DEV</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<PrecompileBeforePublish>True</PrecompileBeforePublish>
<EnableUpdateable>True</EnableUpdateable>
<DebugSymbols>True</DebugSymbols>
<Optimize>False</Optimize>
<UseMerge>True</UseMerge>
<WDPMergeOption>MergeAllOutputsToASingleAssembly</WDPMergeOption>
<SingleAssemblyName>_DEV</SingleAssemblyName>
<DeleteAppCodeCompiledFiles>True</DeleteAppCodeCompiledFiles>
<ExcludeApp_Data>True</ExcludeApp_Data>
<publishUrl>C:\Inetpub\Dev</publishUrl>
<DeleteExistingFiles>True</DeleteExistingFiles>
</PropertyGroup>
PowerShell:
dotnet.exe publish "C:\Projects\ProjectFolder\Project\Project.csproj" --configuration "DEV" --framework netcoreapp2.0 --force --output "C:\Inetpub\Dev"
Related
I have a Visual Studio solution which has several projects. One of them, which is called Extensions is supposed to build a Nuget package. Problem is that if I use MSBuild to build the solution (by executing msbuild from the command prompt), I get the following error for the Nuget package build task:
"C:\git\repo\dirs.proj" (default target) (1:7) ->
"C:\git\repo\sources\dirs.proj" (default target) (2:5) ->
"C:\git\repo\sources\dev\Sdk\CompanyName.ProductName.Extensions.csproj" (default target) (7:6) ->
(GenerateNuspec target) ->
C:\Program Files\dotnet\sdk\5.0.408\Sdks\NuGet.Build.Tasks.Pack\build\NuGet.Build.Tasks.Pack.targets(221,5): error : Could not find a part of the path 'C:\git\ess\target\distrib\Debug\Amd64\CompanyName.ProductName.Extensions'. [C:\git\ess\sources\dev\Sdk\CompanyName.ProductName.Extensions.csproj]
Here is the CSPROJ file I have for this project:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AssemblyName>CompanyName.ProductName.Extensions</AssemblyName>
<RootNamespace>CompanyName.ProductName.Extensions</RootNamespace>
<TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);IncludeCoreAssets</TargetsForTfmSpecificBuildOutput>
<DebugType>full</DebugType>
<DebugSymbols>true</DebugSymbols>
<NuspecFile>CompanyName.ProductName.Extensions.nuspec</NuspecFile>
<PackageOutputPath>$(DistribRoot)\$(Configuration)\$(Platform)\$(MSBuildProjectName)</PackageOutputPath>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<SkipAssemblyComVisible>true</SkipAssemblyComVisible>
<IncludeBuildOutput>false</IncludeBuildOutput>
<OutputPath>$(DistribRoot)\$(Configuration)\$(Platform)\$(MSBuildProjectName)</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<NuspecBasePath>$(OutputPath)</NuspecBasePath>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Core\CompanyName.ProductName.Core.csproj" PrivateAssets="All" />
</ItemGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<Target DependsOnTargets="ResolveReferences" Name="IncludeCoreAssets">
<ItemGroup>
<BuildOutputInPackage Include="#(ReferenceCopyLocalPaths->WithMetadataValue('ReferenceSourceTarget', 'ProjectReference'))" />
</ItemGroup>
</Target>
</Project>
I personally think the issue is that for some reason when MSbuild is trying to create the Nuget package, it's trying to find the Extensions project DLLs in this path: \target\distrib\Debug\Amd64\CompanyName.ProductName.Extensions\, even though it actually built and stored the said binaries in this path earlier: \target\distrib\CompanyName.ProductName.Extensions\. <--- This is something I checked manually myself by examining the 'target' folder after running msbuild.
Visual Studio however doesn't have this issue. When I build this solution within Visual Studio, it stores the binaries for this Extensions project in \target\distrib\Debug\AnyCPU\CompanyName.ProductName.Extensions\ folder, which I think matches the pattern defined in the CSPROJ file:
<OutputPath>$(DistribRoot)\$(Configuration)\$(Platform)\$(MSBuildProjectName)</OutputPath>
Visual Studio also stored the Nuget package in this folder, which is also correct as per the <PackageOutputPath> spec mentioned in the CSPROJ file.
So can someone suggest why MSbuild is storing the built DLLs of this project in \target\distrib\CompanyName.ProductName.Extensions\, but is trying to find them in \target\distrib\Debug\Amd64\CompanyName.ProductName.Extensions\ ?
I think the issue is that for some reason, MSbuild isn't adhering to the <OutputPath> spec mentioned above when it's storing the built DLLs for this project.
I am trying to change the Nu-Get package based on the debugging/release profile in visual studio 2022. This is very similar to This question however none of those solutions are working here. I created a standard console project to connect to Informix using the DB2 libs. Which runs fine. I added "docker support" through right clicking on the project in visual studio and it created a "profile" for Docker. I still have the standard Debug and Release configurations but now I have an additional drop down after the processor selection that has InformixConnect (appName), Docker, and WSL. It runs fine in Docker, which is linux, if I switch the reference manually to the linux version. I am trying to change the PackageReference value in .csproj when Docker is selected. I Tried every variation using Conditional in the linked question above, all failed to work. Any help would be appreciated.
launchsettings.json
{
"profiles": {
"InformixConnect": {
"commandName": "Project",
"commandLineArgs": "192.168.10.29"
},
"Docker": {
"commandName": "Docker"
},
"WSL": {
"commandName": "WSL2",
"environmentVariables": {},
"distributionName": ""
}
}
}
Top of .csproj.user
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ActiveDebugProfile>Docker</ActiveDebugProfile>
<_LastSelectedProfileId>C:\source\tests\InformixConnect\InformixConnect\Properties\PublishProfiles\registry.hub.docker.com_sgums.pubxml</_LastSelectedProfileId>
</PropertyGroup>
current .csproj - I have tried numerous variations on this without success.
<Project Sdk="Microsoft.NET.Sdk;Microsoft.NET.Sdk.Publish">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.14.0" />
<PackageReference Include="Net5.IBM.Data.DB2-lnx" Version="5.0.0.500" Condition="$([MSBuild]::IsOsPlatform('Linux'))" />
<PackageReference Include="Net5.IBM.Data.DB2" Version="5.0.0.500" Condition="$([MSBuild]::IsOsPlatform('Windows'))" />
</ItemGroup>
</Project>
msbuild diag output regardless of profile shows
OS = Windows_NT
The only thing I can see in the msbuild output that is changing is
ActiveDebugProfile = InformixConnect
vs
ActiveDebugProfile = Docker
Tried to run a conditional off every variation of Profile I could think of, but it didn't work.
links to my different msbuild outputs if interested. console app and docker.
Updated -
Feel free to download the repo and check it out. I appreciate everyone's help and would love to get this figured out.
I am using VS 2019 and .Net 5 to build a simple console application. I wanted to share this app with a friend so I tried to publish it as a single file but I keep getting some extra DLLs that the executable needs to run correctly.
Edit: Switching this project to .net core 3.1 works as expected I am able to export a single Exe file without any required DLLs.
Dotnet Cli:
dotnet publish -c Release -o publish -p:PublishReadyToRun=true -p:PublishSingleFile=true -p:PublishTrimmed=true --self-contained true
Csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<PublishSingleFile>true</PublishSingleFile>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="HtmlAgilityPack" Version="1.11.28" />
</ItemGroup>
</Project>
Its known issue that described here: https://github.com/dotnet/runtime/issues/36590
And new dev experience provided here: https://github.com/dotnet/designs/blob/main/accepted/2020/single-file/design.md#user-experience
So in your case you need use p:IncludeNativeLibrariesForSelfExtract=true additionaly.
Full command:
dotnet publish -c Release -o publish -p:PublishReadyToRun=true -p:PublishSingleFile=true -p:PublishTrimmed=true --self-contained true -p:IncludeNativeLibrariesForSelfExtract=true
or include this flag in .csproj file
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<PublishSingleFile>true</PublishSingleFile>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<PlatformTarget>x64</PlatformTarget>
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
</PropertyGroup>
I am trying to use a .pubxml profile in order to deploy my app in gitlab using gitlab job runner.
Here is my yml file
image: mcr.microsoft.com/dotnet/core/sdk:3.0
stages:
- deploy
variables:
test: "Tests/UnitTests/FeatureSwitch.UnitTests"
before_script:
- "dotnet restore"
deploy:
stage: deploy
script:
- "cd FeatureSwitch"
- 'dotnet build -c Release /p:DeployOnBuild=true /p:PublishProfile=Properties/PublishProfiles/Development.pubxml'
This is my profile:
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>MSDeploy</WebPublishMethod>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<LaunchSiteAfterPublish>False</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<TargetFramework>netcoreapp3.0</TargetFramework>
<ProjectGuid>...</ProjectGuid>
<SelfContained>false</SelfContained>
<MSDeployServiceURL>https://...</MSDeployServiceURL>
<DeployIisAppPath>...</DeployIisAppPath>
<RemoteSitePhysicalPath />
<SkipExtraFilesOnServer>False</SkipExtraFilesOnServer>
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
<EnableMSDeployBackup>True</EnableMSDeployBackup>
<UserName>...</UserName>
<_SavePWD>True</_SavePWD>
</PropertyGroup>
</Project>
Also Development.pubxml.user file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<TimeStampOfAssociatedLegacyPublishXmlFile />
<EncryptedPassword>...</EncryptedPassword>
</PropertyGroup>
</Project>
The profile file is auto generated from VS, and it works fine if I click publish from VS.
But it does not work if i run it from gitlab.
The error looks like below:
Build FAILED.
/usr/share/dotnet/sdk/3.0.102/Sdks/Microsoft.NET.Sdk.Publish/targets/PublishTargets/Microsoft.NET.Sdk.Publish.MSDeploy.targets(171,5): error MSB6004: The specified task executable location "%ProgramW6432%/IIS/Microsoft Web Deploy V3/msdeploy.exe" is invalid. [/builds/rajmond.burgaj/featureswitch/FeatureSwitch/FeatureSwitch.csproj]
0 Warning(s)
1 Error(s)
Time Elapsed 00:00:08.21
ERROR: Job failed: exit code 1
After searching I did only find one similar issue here which does not have any answer!
Does anybody know what might be the issue ?
Is this related to gitlab itself or something wrong with commands ?
I use a linux-based docker pipeline to build and do automatic testing with the NUnit Framework in a C#-.NET-Core based solution.
"Test" job in my .gitlab-ci.yml-File:
runTests:
stage: test
image: docker-registry.xyz.de/${CI_PROJECT_PATH}/build:${CI_COMMIT_REF_SLUG}_backend_${CI_COMMIT_SHA}
services:
- name: atsnngs/mysql-aurora-compatible
alias: mysql_test
tags:
- docker
- linux
- shared
variables:
GIT_STRATEGY: none
artifacts:
expire_in: 30m
paths:
- $CI_PROJECT_DIR/pages
script:
- mkdir $CI_PROJECT_DIR/pages
- mkdir mkdir /tmp/pages
- cd /app
- nohup dotnet run --project ./ServiceLoader/ServiceLoader.csproj Test > dotnetcore.log &
- sleep 10s && dotnet test -v normal /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:Exclude=[NUnit3.TestAdapter]*
- reportgenerator -reports:/app/Tests/coverage.opencover.xml -targetdir:/tmp/pages
- ls -l /tmp/pages
- mv /tmp/pages/index.htm /tmp/pages/index.html
- mv /tmp/pages $CI_PROJECT_DIR/
dependencies:
- build
In the Dockerfile, which I use to build the image I am using to execute testing, I install the report generation tool (For readability reasons I skipped the dotnet restore and build parts of the Dockerfile):
FROM microsoft/dotnet:2.1-sdk AS build
# install reportgenerator
RUN dotnet tool install --global dotnet-reportgenerator-globaltool
ENV PATH /root/.dotnet/tools:$PATH
But when I ran the pipeline the report generation fails:
$ reportgenerator -reports:/app/Tests/coverage.opencover.xml -targetdir:/tmp/pages
No report files specified.
I have already compared the Dockerfile and .gitlab-ci.yml file with another project I used this approach and could not find any difference which could explain this error. Is there any other place where I need to have a look at?
Any help is highly appreciated!
The problem is solved through adding the Nuget packages for coverlet.msbuild and dotnet-reportgenerator-cli. These packages are missing and lead to the error in the report generation.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<IsTestProject>true</IsTestProject>
<IsPackable>false</IsPackable>
...
</PropertyGroup>
<ItemGroup>
...
<PackageReference Include="Nunit" Version="3.11.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="coverlet.msbuild" Version="2.4.0" />
<PackageReference Include="dotnet-reportgenerator-cli" Version="4.0.5-rc2" />
</ItemGroup>
</Project>
In my case, I had multiple defined in the csproj file. Removing „net48“ and other legacy .NET framework TFMs helped in my case.