TFS 2015 RC Build.Preview Execute xUnit Tests - msbuild

We are trying to get xUnit tests to run properly using TFS 2015 RC. We're trying to access the test runner stored in our solutions NuGet packages folder which lives in our Build Agent's drop folder.
We are trying to reference the test runner using this path in the "Path to Custom Test Adapters" $(Build.SourcesDirectory)\WebIZ\packages\xunit.runners.1.9.2\tools.The build is able to resolve the path okay (it was failing before with an invalid path message), but now it cannot find the test runner
2015-06-09T20:05:40.4008595Z Executing the powershell script: D:\TFS\Build_vNext\AgentSchlitz\agent\tasks\VSTest\1.0.8\VSTest.ps1
2015-06-09T20:05:41.9947507Z Warning: The path 'D:\TFS\Build_vNext\AgentSchlitz\1c692895\WebIZ\WebIZ\packages\xunit.runners.1.9.2\tools\' specified in the 'TestAdapterPath' does not contain any test adapters, provide a valid path and try again.
extensions. Example: vstest.console.exe myTests.dll /UseVsixExtensions:true
What should the proper configuration be for the "Path to Custom Test Adapters"?
Should the proper configuration be:
$(Build.SourcesDirectory)\WebIZ\packages\xunit.runners.1.9.2\tools*
$(Build.SourcesDirectory)\WebIZ\packages\xunit.runners.1.9.2\tools*

I think you need to use XUnit 2.0 with the Nuget based runners.
There are full instructions in this blog post by Esteban Garcia that goes though the process step by step.
There's too much information and images for me to copy any one bit into this answer as the question is quite broad.

Are you sure that it isn't that you're simply pointing at the tools\ folder instead of the bin\ folder?
e.g.
Path to Custom Test Adapters:
"$(Build.SourcesDirectory)\WebIZ\packages\xunit.runners.1.9.2\bin"
Also, if you're copying that path from a blog post or other source that uses non-standard double quotes, you'll get the path is invalid error. Just retype the double quotes directly in the input box or whatever to make sure you have "raw" double quotes.

In our XUnit configuration, our "path to custom test adapters" is to the solution directory, NOT the xunit custom adapters, and it finds it fine. We actually submitted this pull request: https://github.com/Microsoft/vso-agent-tasks/pull/222 to get the path to custom test adapters treated like a route, and not like a string. Making the same change on your server might help. We have no other custom settings:

I had tried all combinations with the same issue, what fixed this for me was adding the entry to the packages.config for the test project...
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NUnit" version="3.5.0" targetFramework="net45" />
<package id="NUnit3TestAdapter" version="3.5.0" targetFramework="net45" />
</packages>
Even though I had referenced the Nunit3Adapter in the project and solution, the last entry there in the config needed to be manually added.

Related

How to kill VBCSCompiler.exe on Ubuntu agent?

I created an Azure Devops Build pipeline and i am trying to build my ASP.NET MVC and Angular hybrid site project on bitbucket (git).
The project first gets checked out, and nuget restores the necessary packages, and then the .NET builds. I used windows 2019 as azure pipeline agent for the build to succeed. however, Its taking about 7 minutes to complete, whilst running the tasks (besides .Net) on a ubuntu agent is much faster! takes around 2 mins instead!
Therefore, I'd like to use ubuntu, but im running into an issue with the MSBuild task...
"/home/vsts/work/1/s/Bobby.ProjectA/Bobby.ProjectA.csproj" (default target) (1) ->
(KillVBCSCompilerAndRetryCopy target) ->
/home/vsts/work/1/s/packages/Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.8/build/net45/Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props(23,5):
error MSB4044: The "KillProcess" task was not given a value for the required parameter "ImagePath". [/home/vsts/work/1/s/Bobby.ProjectA/Bobby.ProjectA.csproj]
According to this post, VBCSCompiler.exe continues running from the Compiler Nuget package (nuget restore task?) so it locks the src folders and prevented future builds from running, e.g. causing error like this:
/home/vsts/work/1/s/packages/Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.8/build/net45/Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props(17,5):
warning MSB3021: Unable to copy file "/home/vsts/work/1/s/packages/Microsoft.Net.Compilers.2.4.0/build/../tools/csc.exe" to "/bin/roslyn/csc.exe". Access to the path '/bin/roslyn' is denied. [/home/vsts/work/1/s/Bobby.ProjectA/Bobby.ProjectA.csproj]
So the solution would be to kill the VBCSCompiler.exe but since i cant actually access the hosted machine during the build, im not sure how to do that.
screenshot of my pipeline so far:
Am i facing a dead-end path here with this approach? The build runs fine on windows 2019 but it just takes too long, so thats why if i can make it run on ubuntu successfully that would be great!
You can have a try with below workarounds:
1,Set MSBUILD arguements /p:UseSharedCompilation=false.
You can add above arguement to the msbuild arguements field of the msbuild task. See here.
2,Upgrade Microsoft.CodeDom.Providers.DotNetCompilerPlatform nupkg to the latest and remove Microsoft.Net.Compilers nupkg from your project. See here for more information.
3, Try Specifing the TTL of Roslyn compiler server.
You can define a pipeline variable VBCSCOMPILER_TTL on the Variable tab to specify a shorter idle time for VBCSCompiler.exe
Or you can add <providerOption name="CompilerServerTimeToLive" value="[num of seconds]" /> under system.codedom/compilers/compiler in the config file. See here for more information.
4, Use CheckIfShouldKillVBCSCompiler target:
You can try add below to your csproj file:
<Target Name="CheckIfShouldKillVBCSCompiler">
<PropertyGroup>
<ShouldKillVBCSCompiler>true</ShouldKillVBCSCompiler>
</PropertyGroup>
</Target>
See here.
The build on Ubuntu 20 finally worked! I don't know why removing these lines resolved the VBCSCompiler issue, but by doing so, the msbuild completed successfully on Ubunutu 20 agent!!
Remove the following lines from the .csproj file:
<Import Project="..\packages\Microsoft.Net.Compilers.2.4.0\build\Microsoft.Net.Compilers.props" Condition="Exists('..\packages\Microsoft.Net.Compilers.2.4.0\build\Microsoft.Net.Compilers.props')" />
<Error Condition="!Exists('..\packages\Microsoft.Net.Compilers.2.4.0\build\Microsoft.Net.Compilers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Net.Compilers.2.4.0\build\Microsoft.Net.Compilers.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.8\build\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.8\build\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props'))" />
To give some context to the answer, this post here indicated that converting from MSBuild-Integrated Package Restore to Automatic Package Restore (nuget restore task) implied that the Microsoft.Net.Compilers <Import> and <Error Condition> snippets are no longer relevant/needed in the .csproj file.

MSBUILD Dynamically Create Config XML Dotfuscator

I am trying to obfuscate bunch of files in a directory and every build there are more and more files being generated. I would like to know if there is a way I can dynamically create the Dotfuscator configuration xml file using a MSBUILD task that will generate the xml file every time there is a new file added to the directory?
This might be a good time to use the Directory input. Rather than representing a single assembly (.exe or .dll), this type of Dotfuscator input captures all the assemblies in a directory. When the contents of the directory change, Dotfuscator's build will automatically pick up any new assemblies.
To make a Dotfuscator config file with a Directory input, open the GUI and add an input as you normally would (directions for Community Edition's GUI and for Professional Edition's standalone GUI), but instead of selecting a file from the Browse... dialog, just navigate to the directory and click "Open" while the "File name" is still listed as "Folder Select". Then, save your configuration.
From now on, whenever you run Dotfuscator (whether from the standalone GUI, the command line, the Visual Studio integration, or the MSBuild task), all assemblies in the directory will be processed as input.
Note: If you look at the config file itself, you might be surprised that it will still list individual assemblies:
<input>
<loadpaths />
<asmlist>
<package refid="19e1b0c5-7221-476f-af4b-bafef68edc95">
<file dir="C:\code\BasicTestApp\BasicTestApp\bin" name="Debug" />
<asmlist>
<inputassembly refid="a6da5d8d-c181-4103-840d-d8cc7c85937a">
<option>honoroas</option>
<option>stripoa</option>
<option>transformxaml</option>
<file dir="" name="BasicTestApp.exe" />
</inputassembly>
<inputassembly refid="df84dad0-fbe8-49ab-b8c8-9fb59e706785">
<option>honoroas</option>
<option>stripoa</option>
<option>library</option>
<option>transformxaml</option>
<file dir="" name="ClassLibrary.dll" />
</inputassembly>
</asmlist>
</package>
</asmlist>
</input>
Despite this layout, Dotfuscator will process all assemblies in the C:\code\BasicTestApp\BasicTestApp\bin\Debug directory when it runs a build based off this config file, not just those two listed.
The assembly elements in the config are just there so that you can still make rules against individual assemblies in the GUI (e.g., to make one assembly be in Library Mode).
The list represents the state of the directory when the GUI last modified the config.
Disclaimer: I work for the Dotfuscator team, and am answering this question as part of my job.
Additional note due to clarification in the comments: the directory package has a feature where you can exclude certain assemblies from obfuscation. These assemblies will be treated as a Package Artifact and just copied from input-to-output without modification. Any obfuscated assemblies that refer to these excluded assemblies will still be processed correctly.
To do this in the GUI, right-click on the assembly within the package, and select "Exclude assembly from package". Or, if you'd prefer to edit the config file, add the following <option> tag as a child of each relevant <inputassembly> tag:
<option>artifact</option>
The latest Dotfuscator version 4.41.1 has the latest flag
true
This will generate the Dotfuscator config file if the file is missing. Also you can add this to the csproj as documented in the latest getting started guide https://www.preemptive.com/dotfuscator/pro/userguide/en/getting_started_protect.html

How can I pass MSDeploy-style parameters to MSBuild via the commandline?

I am setting up TeamCity to deploy our Website Project application (using a *.wdproj) and Web Deploy application to IIS.
I have a build configuration that uses MSBuild.exe with the MSDeployPublish to build and then deploy the application.
We now want to get the application to deploy to multiple target environments, therefore need a way to supply different settings based on the target environment.
I have added a parameters.xml file to the Web Deployment Project, and have verified that the parameters set in here are making all the way through the target IIS server and being correctly applied - great!
Now what I want to do is have different parameter settings per environment. I was hoping I could use something like the MSDeploy.exe -setParam argument to specify different values for each environment, however I can find no way to get my parameter values into MSBuild via the commandline.
I suspect I might need to do one of the following:
Split MSBuild and MSDeploy into separate build steps.
Configure a task somewhere in the pipeline to take 1 of n versions of parameters.something.xml and move it into parameters.xml so it gets picked up by the rest of the pipeline.
I'm looking for the simplest way to move ahead at this point, any suggestions welcome.
For reference, here is the command I'm experimenting with now:
msbuild /target:MSDeployPublish MySite_deploy.wdproj /P:Configuration=Debug
/P:DeployOnBuild=True /P:DeployTarget=MSDeployPublish
/P:MsDeployServiceUrl=www.myserver.com:8172/MsDeploy.axd
/P:AllowUntrustedCertificate=True /P:MSDeployPublishMethod=WMSvc
/P:CreatePackageOnPublish=True /P:UserName=MyUser /p:Password=MyPassword
/P:DeployIisAppPath=www.myserver.com/MySite
/P:ServerURL=http://www.tryingtoforcethis.com
It's working beautifully except the value for ServerURL, which is a parameter I've defined in my parameters.xml, is not making its way into the target site. The default I specified in parameters.xml, however, is. So I know that the parameters are working, I just can't figure out how to add them to the msbuild commandline.
Well, I think the short answer is that with MSBuild 4.0 and VS2010, you can't just pass arbitrary parameters into MSDeployPublish from the call to MSBuild.
I found these posts helpful:
http://forums.iis.net/t/1167657.aspx/1 - Ming Chen's comments
http://www.hanselman.com/blog/TinyHappyFeatures3PublishingImprovementsChainedConfigTransformsAndDeployingASPNETAppsFromTheCommandLine.aspx - the comments from Richard Szalay at the bottom
After reading these, and sifting through the Microsoft.Web.Publishing.targets file for some time trying to find a "way in", I finally settled on having multiple copies of Parameters.xml in my project folder in source control, labelled according to their environment eg:
Parameters.Test.xml
Parameters.Staging.xml
Parameters.Live.xml
Then, prior to the package and deploy, I just copy one of these files into Parameters.xml and it gets picked up by the rest of the pipeline - done!
BTW I had a temporary problem getting the parameters.xml copy and subsequent cleanup to work within a single MSBuild.exe call due to what seems to be some sort of file access issue, I've detailed it here:
MSBuild.exe Copy task not working properly unless a version of the file already appears in target
To answer your question, the parameterization of your command line is not a concern of MSBuild. Instead, you should utilize external tools. For example, if you run your msbuild command from a batch file you could pass the parameters to the batch file and run it for each environment with different parameters. Another approach is to use a build system like TeamCity or VSTS and utilize their parameterization mechanism. Adapted for the VSTS or TFS, your command could look like this:
msbuild MySite_deploy.wdproj /target:MSDeployPublish /p:Configuration=Debug
/p:DeployOnBuild=True /p:MsDeployServiceUrl=$(IIsHostNameIp)
/p:AllowUntrustedCertificate=True /p:MSDeployPublishMethod=WMSvc
/p:CreatePackageOnPublish=True /p:UserName=$(IIsUserName) /p:Password=$(IIsPassword)
/p:DeployIisAppPath=$(IIsSite)
In addition, I would suggest some clean up for your origianl command line:
Using both /p:target and /p:DeployTarget is redundant. Any one of them is enough. Also it could be replaced with /p:WebPublishMethod.
For /p:MSDeployServiceUrl it is enough to only provide a DNS name or IP. the port and the Url is automatically derived from the /p:MSDeployPublishingMethod=WMSVC.
The custom parameter /p:ServerURL is unknown and won't be mapped anywhere.
msbuild.exe {build-script.proj} /property:{someParameter=someValue}
In your build script you can use $(someParameter) as a variable

Web Deploy - Using Relative Paths for local file system deployment

I am wanting to use Web Deploy to run a custom deployment setup.
As I am wanting to have this work fine when running on many different environments (team members local machines, 4 different builds servers) I want to deploy to a local path that is relative.
What I am wanting to do is:
Deploy to a local relative path
Have the after build step do magical things...
However when i enter the local file path to deploy to as: "..\Deploy_Production"
web deploy complains with this:
2>Connecting to ..\Deploy_Live...
2>Unable to create the Web site '../Deploy_Live'. The URL http://:0 is invalid.
Its as if Web deploy thinks that the relative file path is a website URL. Using "..\" instead doesn't help my cause.
How do you get WebDeploy to deploy to a local relative path?
Edit 1:
I have tried to use a ConvertToAbsolutePath task before build, to no avail:
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<SiteUrlToLaunchAfterPublish>http://mywebsite.com</SiteUrlToLaunchAfterPublish>
<publishUrl>..\Deploy_Production</publishUrl>
<DeleteExistingFiles>False</DeleteExistingFiles>
</PropertyGroup>
<Target Name="BeforeBuild">
<ConvertToAbsolutePath Paths="$(publishUrl)">
<Output TaskParameter="AbsolutePaths" PropertyName="publishUrl" />
</ConvertToAbsolutePath>
</Target>
Edit 2:
The above works, but only when running commandline builds against the Solution file not a project file
We have a bug here, when publishing using File system you have to provide a full path. We actually found this bug earlier this week. It will be fixed in our next update. In this case when the relative path is passed it incorrectly thinks that its an IIS path.
As a workaround you can edit the .pubxml to make the publishUrl a fullpath. Fortunately you can use an MSBuild property so that this works in team scenarios. Here is what you should do, edit your .pubxml file and update the value of publishUrl to be the following.
<publishUrl>$(MSBuildThisFileDirectory)..\..\..\Deploy_Production</publishUrl>
This path will be relative to the .pubxml file itself. I've verified that this works from both the command line as well as the publish dialog. If you have any issues with this let me know, but the fix should hopefully be released in a few months [no guarantees of course :) ].

Running custom MSBuild tasks as part of the git deployment to Azure WebSites

Problem
As part of my csproj I have a custom MSBuild task that executes the YUICompressor and generates a compiled css and js file.
<PropertyGroup>
<CssOutputFile>$(OutDir)..\Styles\compiled.css</CssOutputFile>
<JavaScriptOutputFile>$(OutDir)..\Scripts\compiled.js</JavaScriptOutputFile>
<BuildDependsOn Condition="'$(Configuration)' != 'Debug'">
$(BuildDependsOn);
CompressorTarget;
</BuildDependsOn>
</PropertyGroup>
This runs fine as part of the git deployment and the file is being generated, however the Azure Web Sites deployment engine will then copy all the output files to another folder. In that process it seems it takes whatever you have in your csproj instead of whatever you have in the folder. That menas that the generated compiled.css and compiled.js won't be copied (because they are not in my csproj)
What Azure does to deploy your project should be exactly the same as if you do the following:
Right click on the project and choose Publish
Change the Publish Method to 'File System'
Enter a path and click Publish
So generally, you'll want to make sure that your build process works such that you get the right file when you do this local publish. If it does, then chances are you'll get the same results when git pushing to Azure.
The workaround I used for now is adding an empty compiled.css and .js file to the csproj and I wanted to write this question in case someone goes through the same thing.
It would be great if someone from MS can comment if there are plans on doing something different for this scenario.
Depending on where you place the compiled scripts, you can use star-includes in your project file:
<ItemGroup>
<Content Include="assets\**\*" />
</ItemGroup>
If Azure uses your project file to determine what gets deployed (which seems somewhat strange to start with), then that should work.