Publish code coverage using .coverage file? - azure-devops

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>

Related

Azure build pipeline publishUrl nesting indefinitely

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.

Can't exclude *.dcproj from dotnet pack

I used Visual Studio 2017 to make a solution with docker-compose support. When I try to pack a nuget package (during a CI process) using dotnet pack MySolution.sln I getting the error MSB4057 saying that it cannot pack the docker-compose.dcproj project. So I tried to use <IsPackable>false</IsPackable> inside my docker-compose.dcproj with no success.
So I have to pack my projects one by one or use different solutions for CI and for debugging process - both solutions looks ugly to me.
Does anyone have an idea how to exclude .dcproj file from trying to been packed by dotnet pack?
In the CI script, remove the docker-compose project from the solution before the pack command with
dotnet sln MySol.sln remove docker-compose.dcproj
I had the same problem and I have solved it by adding a dummy "Pack" target to docker-compose.dcproj, so my project looks like this:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" Sdk="Microsoft.Docker.Sdk">
<PropertyGroup Label="Globals">
<ImportDirectoryBuildProps>false</ImportDirectoryBuildProps>
<ImportDirectoryBuildTargets>false</ImportDirectoryBuildTargets>
<ProjectVersion>2.1</ProjectVersion>
<DockerTargetOS>Windows</DockerTargetOS>
<ProjectGuid>0a1c7d45-3174-4d07-a025-4d5fd55042c0</ProjectGuid>
<IsPackable>false</IsPackable>
<IsTestProject>false</IsTestProject>
</PropertyGroup>
<PropertyGroup>
<DockerServiceName>app-name</DockerServiceName>
</PropertyGroup>
<ItemGroup>
<None Include="docker-compose.override.yml">
<DependentUpon>docker-compose.yml</DependentUpon>
</None>
<None Include="docker-compose.yml" />
</ItemGroup>
<Target Name="Pack">
</Target>
</Project>

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

NuGet Package Restore: Visual Studio Online & POSTSHARP

I installed POSTSHARP as a nuget package and I want Visual Studio Online to automatically restore it.
POSTSHARP must be restored before build though.
I am trying to follow this with no success: link
How can I run scripts / commands in Visual Studio Online BEFORE build?
There are instructions on nuget.org on how to set up a package restore with TFS, including Visual Studio Online: http://docs.nuget.org/docs/reference/package-restore-with-team-build
It mentions that the default Build Process Templates for VSO already implements NuGet Package Restore workflow. So, supposedly, you need to do additional setup only when you customize the templates.
The proposed approach is to create a simple MSBuild project file that will be used to build the solution. You can include all the required targets there (e.g. Build, Rebuild, Clean) that will just invoke MSBuild on your solution file with specifying the corresponding target.
Additionally create a target for package restore - it will invoke NuGet.exe restore MySolution.sln command. The common build targets will depend on this one.
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0"
DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<OutDir>$(MSBuildThisFileDirectory)bin</OutDir>
<Configuration>Release</Configuration>
<ProjectProperties>
OutDir=$(OutDir);
Configuration=$(Configuration);
</ProjectProperties>
</PropertyGroup>
<ItemGroup>
<Solution Include="$(MSBuildThisFileDirectory)src\*.sln" />
</ItemGroup>
<Target Name="RestorePackages">
<Exec Command=""$(MSBuildThisFileDirectory)tools\NuGet\NuGet.exe" restore "%(Solution.Identity)"" />
</Target>
<Target Name="Build" DependsOnTargets="RestorePackages">
<MSBuild Targets="Build"
Projects="#(Solution)"
Properties="$(ProjectProperties)" />
</Target>
<!-- other targets... -->
</Project>

Is there a way to create more than one deployment with msbuild on a single build?

I am using msbuild command line multiple times to create a deployment zip file for my dev / test / production websites. I have already configured the parameters and configuration xml for each one. I want to know if i can condense my 3 calls to msbuild down to one, and have it build all three at once?
right now i have to run
msbuild.exe myproject.sln /T:Build /p:DeployOnBuild=True /p:PublishProfile="Dev Server"
msbuild.exe myproject.sln /T:Build /p:DeployOnBuild=True /p:PublishProfile="Prod Server"
etc
The continuous deployment solution i'm using (bamboo) is struggling with this multiple call to msbuild for some reason (i have an open ticket and they are perplexed as well). I'm trying to simplify things.
I have a template for building out all skus of the same solution in parallel.
This is the same concept as Stijn's approach that uses an ItemGroup as a project definition rather than a series of options for a particular property + the msbuild task will build both at the same time, saving you time and bubbling up any configuration issues when building in parallel.
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<SolutionToBuild Include="$(MSBuildThisFileDirectory)\MyProject.sln">
<Properties>DeployOnBuild=True;PublishProfile="Dev Server"</Properties>
</SolutionToBuild>
<SolutionToBuild Include="$(MSBuildThisFileDirectory)\MyProject.sln">
<Properties>DeployOnBuild=True;PublishProfile="Prod Server"</Properties>
</SolutionToBuild>
</ItemGroup>
<Target Name="Build">
<MsBuild BuildInParallel="true" ContinueOnError="true" Projects="#(SolutionToBuild)" />
</Target>
<Target Name="Clean">
<MsBuild BuildInParallel="true" ContinueOnError="true" Projects="#(SolutionToBuild)" Targets="Clean" />
</Target>
</Project>
You can only invoke multiple different targets on the commandline, but you can't supply multiple different values for properties. At least not in a way that I'm aware off. The workaround however is simple, easier to extend than a commandline, and the typical msbuild way of doing things: create a master build file like below and call it from Bamboo instead of the solution.
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
DefaultTargets=Build>
<Target Name="Build">
<ItemGroup>
<PublishProfiles Include="Dev Server"/>
<PublishProfiles Include="Prod Server"/>
</ItemGroup>
<MsBuild Projects="myproject.sln" Targets="Build"
Properties="DeployOnBuild=True;PublishProfile=%(PublishProfile.Identity)"/>
</Target>
</Project>
(this will invoke MsBuild myproject.sln once for each item in the PublishProfiles list with the properties as shown)