Azure build pipeline publishUrl nesting indefinitely - azure-devops

I just took over DevOps of a continuously integrated, continuously delivered Azure build pipeline, and all was going well… until today, when it's begun failing. I think the failures are due to an overlong file path on the web server.
Here is my error message:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VisualStudio\v16.0\Web\Microsoft.Web.Publishing.targets(3000,5): Error : Copying file bin\Release\Published\bin\Release\Published\bin\Release\Published\bin\Release\Published\bin\Release\Published\bin\Release\Published\bin\Release\Published\bootstrap\fonts\glyphicons-halflings-regular.eot to obj\Release\Package\PackageTmp\bin\Release\Published\bin\Release\Published\bin\Release\Published\bin\Release\Published\bin\Release\Published\bin\Release\Published\bin\Release\Published\bootstrap\fonts\glyphicons-halflings-regular.eot failed. Could not find a part of the path 'obj\Release\Package\PackageTmp\bin\Release\Published\bin\Release\Published\bin\Release\Published\bin\Release\Published\bin\Release\Published\bin\Release\Published\bin\Release\Published\bootstrap\fonts\glyphicons-halflings-regular.eot'.
Process 'msbuild.exe' exited with code '1'.
Evidently, it's just been dumping the project files into an ever-deeper rabbit hole of nested bin\Release\Published directories!
I checked what the resultant server path would be, and it amounts to 262 characters. My understanding is that this is longer than the Windows MAX_PATH value of 260, and I think that this is why my build is failing.
But I can't figure out how to stop that from happening.
My .pubxml file looks like this…
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<PublishProvider>FileSystem</PublishProvider>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<publishUrl>bin\Release\Published</publishUrl>
<DeleteExistingFiles>False</DeleteExistingFiles>
</PropertyGroup>
</Project>
…but I end up with a bottomless pit of bin\Release\Published\bin\Release\Published\bin\Release\Published\bin…!!
I've updated the .pubxml file and checked it in successfully, but that seemed to have no effect. Here are my "Visual Studio build" pipeline details:
https://i.stack.imgur.com/jNO9U.png
$(BuildPlatform) = any cpu and $(BuildConfiguration) = release. I've tried supplying a different MSBuild argument for /p:PublishUrl, but that also didn't work.
How can I get this endless nesting to stop and my project to build!?
Thank you.

Related

Azure pipeline and DotNet core project: Unable to load the service index for source api.nuget.org

I was given the task to create a pipeline on our Windows Self Hosted agent to build a DotNet Core project located on GitHub.
I have a pipeline that does that already and works well but using it with the second project, it fails with this message:
Determining projects to restore...
C:\Program Files\dotnet\sdk\5.0.100\NuGet.targets(131,5): error : Unable to load the service index for source https://api.nuget.org/v3/index.json. [E:\Agent\_work\24\s\src\myProject\ myProject.csproj]
C:\Program Files\dotnet\sdk\5.0.100\NuGet.targets(131,5): error : Response status code does not indicate success: 302 (Moved Temporarily). [E:\Agent\_work\24\s\src\ myProject \ myProject.csproj]
##[error]Cmd.exe exited with code '1'.
We have firewall constraints so we have setup an artifact feed with upstream source to Nuget, I cannot tell for sure that the project that works tries to use it but at least, it does not fail. I am not the author of the projects and don’t use Nuget a lot, could I have some help finding what can be the issue? Would it be burried in the Nuget files of the project ?
Ok, I added a nuget.config file to the solution with path to my feed with the upstream:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="REPO" value="https://...com//_packaging/REPO/nuget/v3/index.json" />
</packageSources>
</configuration>
Used only this in my YAML:
- task: NuGetAuthenticate#0
displayName: 'Step 1: Authenticate with NuGet'

Nuget Pack Failure - The process cannot access the file 'D:\a\1\a\*.nupkg'

Error on Azure Pipeline for NuGet Pack task, using a SDK format .csproj, which autogenerates the .nuspec file:
The process cannot access the file 'D:\a\1\a\*.nupkg' because it is being used by another process.
System.IO.IOException: The process cannot access the file 'D:\a\1\a\*.nupkg' because it is being used by another process.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.File.InternalDelete(String path, Boolean checkHost)
at NuGet.Commands.PackCommandRunner.BuildPackage(PackageBuilder builder, String outputPath, Boolean symbolsPackage)
at NuGet.Commands.PackCommandRunner.BuildFromProjectFile(String path)
at NuGet.CommandLine.PackCommand.ExecuteCommand()
at NuGet.CommandLine.Command.ExecuteCommandAsync()
at NuGet.CommandLine.Command.Execute()
at NuGet.CommandLine.Program.MainCore(String workingDirectory, String[] args))
##[error]An error occurred while trying to pack the files.
The .csproj file being built, uses TargetsForTfmSpecificBuildOutput:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Description>Provides a .....</Description>
</PropertyGroup>
<PropertyGroup>
<TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage</TargetsForTfmSpecificBuildOutput>
</PropertyGroup>
<Target Name="CopyProjectReferencesToPackage" DependsOnTargets="BuildOnlySettings;ResolveReferences">
<ItemGroup>
<!-- Filter out unnecessary files -->
<_ReferenceCopyLocalPaths Include="#(ReferenceCopyLocalPaths->WithMetadataValue('ReferenceSourceTarget', 'ProjectReference')->WithMetadataValue('PrivateAssets', 'All'))" />
</ItemGroup>
<!-- Print batches for debug purposes -->
<Message Text="Batch for .nupkg: ReferenceCopyLocalPaths = #(_ReferenceCopyLocalPaths), ReferenceCopyLocalPaths.DestinationSubDirectory = %(_ReferenceCopyLocalPaths.DestinationSubDirectory) Filename = %(_ReferenceCopyLocalPaths.Filename) Extension = %(_ReferenceCopyLocalPaths.Extension)" Importance="High" Condition="'#(_ReferenceCopyLocalPaths)' != ''" />
<ItemGroup>
<!-- Add file to package with consideration of sub folder. If empty, the root folder is chosen. -->
<BuildOutputInPackage Include="#(_ReferenceCopyLocalPaths)" TargetPath="%(_ReferenceCopyLocalPaths.DestinationSubDirectory)" />
</ItemGroup>
</Target>
The above modification to the .csproj file is needed due to legacy dll's being required to be built which can't be packaged up on their own. But is based on this answer: https://stackoverflow.com/a/59893520/1231374
Note: Removing the custom package steps still causes the error.
There is an additional error before this, not sure if this could be related.
Error NU5128: Some target frameworks declared in the dependencies group of the nuspec and the lib/ref folder do not have exact matches in the other location. Consult the list of actions below:
- Add a dependency group for .NETStandard2.0 to the nuspec
See the task configuration below:
See the Nuget installer task, which is the first task the installer runs:
I finialy found a "reason" to this problem.
I can't use dotnet cli on my side because my project is not compatible, but I find a workaround.
It seems related to that https://github.com/NuGet/Home/issues/8713, so I used the "Nuget Tool Installer" to force version "5.2.x" and it just works as expected.
I don't understand why this problem is present since 5 minor versions !
The resolution for my problem was to use dotnet pack (as I am working with .NetStandard and .NetCore projects) instead of nuget pack.
In particular to enable the Do not build option. As a pervious step builds the solution and projects within it.

Publish code coverage using .coverage file?

I have an Azure build pipeline with VSTest task that generates code coverage as '.coverage' format. I need to publish this back to the 'Code Coverage' tab in the build result page. Only the download code coverage result is available. How to publish code coverage using '.coverage' file?
I already tried the ReportGenerator tool but when I pass the '.coverage' file to the tool as the report file it gives back the coverage report as zero coverage. When I open the coverage file using visual studio it shows the coverage.
I had the same question and just figured it out. I run the testing with MsBuild from a simple Exec-task and have embedded the logging command as a Message-task. Of course you can produce the same output using PowerShell or something else.
<?xml version="1.0" encoding="utf-8"?>
<Project
ToolsVersion="14.0"
DefaultTargets="ReportCoverage"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
..
<Target Name="ReportCoverage">
..
<ItemGroup>
<CoverageResults Include="$(BinDir)\Reports\*.coverage" />
</ItemGroup>
<Message
Text="##vso[task.addattachment type=Distributedtask.Core.CodeCoverage;name=CodeCoverage;]$(CoverageResults)"
Importance="High"
Condition="'%(CoverageResults.Identity)' != ''"/>
</Target>
</Project>

PostSharp PSSLN gives "Unexpected XML element: LoggingProfiles"

When using PSSLN file, I get the following error in TFS MSBUILD. How do I fix it? The project builds in VisualStudio.
Here is the snippet from TFS build log
Windows\NewProject.pssln (4, 4) Unexpected XML element: LoggingProfiles.
Windows\packages\PostSharp.5.0.29\build\PostSharp.targets (329, 5)
The process C:\ProgramData\PostSharp\5.0.29\bin.Release\postsharp-net40-x86-native.exe exited with code 11
PostSharp 5.0 logging is a complete rewrite of the log aspect.
Please refer to their documentation regarding this, in particular, check out Customizing the Appearance of Log Records.
More specifically, LoggingProfiles was replaced with Logging as you can see in the quote below. Also, I'd suggest using postsharp.config instead of the old pssln file, although based on the documentation it should work as well.
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.postsharp.org/1.0/configuration">
<Logging xmlns="clr-namespace:PostSharp.Patterns.Diagnostics;assembly:PostSharp.Patterns.Diagnostics">
<Profiles>
<LoggingProfile Name="Default" IncludeSourceLineInfo="True">
<DefaultOptions>
<LoggingOptions IncludeParameterType="True"/>
</DefaultOptions>
</LoggingProfile>
</Profiles>
</Logging>
</Project>
Good luck.

VS Publish, Web Deploy - create Event Source

I want to create an new event log Event Source to log my webAPI app to when I Import Application through IIS.
I publish my application to a web deploy folder (zip) file in VS2015 and import from this.
I have found this code to create the event source:
if ([System.Diagnostics.EventLog]::SourceExists("myWeb.API") -eq $false) {
[System.Diagnostics.EventLog]::CreateEventSource("myWeb.API", "Application")
}
and I can put this in a EventSource.ps1 file which does what I want when I run it from a prompt.
How can I execute this during the IIS Import Application process?
I have tried using the .pubxml file but which element to use/override/call-it-via baffles me - I've tried AfterAddIisSettingAndFileContentsToSourceManifest and PipelineDependsOn.
<Target Name="CustomCreateEventSource">
<Message Text="Create Event Source" Importance="high"/>
<PropertyGroup>
<EventSource Condition=" '$(EventSource)'=='' ">
myWeb.API
</EventSource>
</PropertyGroup>
<Exec Command="powershell.exe"
-NonInteractive
-executionpolicy Unrestricted
-file "$(PublishUrl)Publish\EventSource.ps1" "$(EventSource)"" /></Target>
I'd rather it was done via IIS Import Application, as a 1-hit process, and not a:
Import Application
Run the powershell
because it'll be imported by not-necessarily technical users.
Many thanks for taking the time to assist!
You can use the <projectName>.wpp.targets file to kick off a custom command when the application is imported into IIS.
For example, if your project name is MyApp, add a file called MyApp.wpp.targets to the root level of the project.
I tested and verified that this approach works using a targets with the following content:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="CustomTask" AfterTargets="AddIisSettingAndFileContentsToSourceManifest">
<ItemGroup>
<MsDeploySourceManifest Include="runCommand">
<!-- specify InputFormat None (see http://stackoverflow.com/questions/4238192/running-powershell-from-msdeploy-runcommand-does-not-exit) -->
<Path>powershell.exe -ExecutionPolicy bypass -NoLogo -inputformat none -NonInteractive -Command .'$(_MSDeployDirPath_FullPath)\Deploy\createEventLog.ps1'</Path>
</MsDeploySourceManifest>
</ItemGroup>
</Target>
</Project>
One important thing to note is that Visual Studio will sometimes cache the .wpp.targets file. The only way I know to release it is to restart Visual Studio. I just experienced this issue which threw me off track for a while, because I was getting an error that I couldn't make go away.
For reference, here is the .pubxml file I used to create the package Zip:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>Package</WebPublishMethod>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<DesktopBuildPackageLocation>c:\temp\IISImportTestPkg.zip</DesktopBuildPackageLocation>
<PackageAsSingleFile>true</PackageAsSingleFile>
<DeployIisAppPath>Default Web Site/IISImportTest</DeployIisAppPath>
<PublishDatabaseSettings>
<Objects xmlns="" />
</PublishDatabaseSettings>
</PropertyGroup>
</Project>
Lastly, here are a couple of resources that may help:
This is where I picked the idea of usin .wpp.targets file: http://sedodream.com/2011/11/08/SettingFolderPermissionsOnWebPublish.aspx
List of MsDeploy Providers where I found the runCommand provider: https://technet.microsoft.com/en-us/library/dd569040(v=ws.10).aspx