TFS 2013 Build: Cannot leave solution/project files field blank - powershell

I'm using the build process template that comes with TFS 2013 (TfvcTemplate.12.xaml). I want to create a new build definition that runs a bunch of PowerShell scripts; however, I do not have anything .NET to build. TF build does not seem to like that. I'm getting this error below when leaving the solution/project files field blank. Is there any way to get around this?
TF215097: An error occurred while initializing a build for build definition \MyProjectRoot\MyBuildDefinition:
Exception Message:
The process parameter ProjectsToBuild is required but no value was set. A value must be set on the definition or when the build is queued (Category: #200 Build, Display Name: 1. Projects). (type ArgumentException)
Exception Stack Trace:
at Microsoft.TeamFoundation.Build.Hosting.BuildWorkflowInstance.ValidateParameters(BuildWorkflowDefinition definition, IDictionary`2 passedInParameterValues) at Microsoft.TeamFoundation.Build.Hosting.BuildWorkflowInstance.Initialize(BuildWorkflowDefinition definition, IDictionary`2 dataContext)
at Microsoft.TeamFoundation.Build.Hosting.BuildWorkflowManager.TryStartWorkflow(WorkflowRequest request, WorkflowManagerActivity activity, BuildWorkflowInstance& workflowInstance, Exception& error, Boolean& syncLockTaken)

In TFS 2015 (or Visual Studio Online) the new TFS Build system no longer has this limitation.
In TFS 2013 what I often do (to avoid having to muck around with the workflow), is just provide a dummy MSBuild .proj file that does nothing.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" InitialTargets="Build">
<Target Name="Build">
<Message Text="This MSBuild is a placeholder and does nothing" />
</Target>
</Project>

An alternative to Dylan's solution, but something very similar that I do is to create an empty Solution file (.sln) in visual studio and mention that within the build definition/workflow.

You'll need to create your own Process Template (you can probably steal quite a bit from the standard template), and you'll need to rip out the Run MsBuild for Project activity as well as the parameters that are defined specifically for that activity (that will be quite a bit of the default template).
That should allow you to jump directly to the powershell sections.

Related

How to activate "treat warning as error" for specific build definitions?

I would like to make my main branch TFS build definitions to treat warnings as errors so that the build fails when the projects are not error free. Since I do not want to activate "treat error as warning" in all project as a default, my first idea was to add a powershell script to my main build definition that substitues false with true in the line <TreatWarningsAsErrors>...</TreatWarningsAsErrors> in all csproj files it finds (something along the line of this). Is there any better/straighter way via some option as part of the build definition settings?
In the build definition specify /p:TreatWarningsAsErrors=True in the MSBuild argument field.
This will override any setting from the csproj files.
Unfortunately, there is no this kind of settings as part of the build definition.
However, you could be able to return warnings and errors from your powershell script using logging commands. With using task.logissue type=error you could fail the build task and then fail the build.
More details you could take a look at this similar question: Is it possible to raise and display build warnings from build steps using TFS 2015

web.config changes via TFS 2015 Release Management

In the past I've using web.config transforms when manually deploying code to set environment specific setting values and attributes. I am transitioning from environment specific manual builds to a single TFS 2015 Build deployed to multiple environments via Release Management. Environment specfic application settings values configured in the web.config are tokenized. This method essentially inserts tokens into setting values during the build process. When deployed the tokens are replaced with matching Release definition configuration values.
This method is insufficient setting attributes of non-settings however. Examples of these transforms include:
<httpCookies requireSSL="true" xdt:Transform="Insert" />
<compilation xdt:Transform="RemoveAttributes(debug)" />
<httpRuntime xdt:Transform="RemoveAttributes(executionTimeout,maxRequestLength,useFullyQualifiedRedirectUrl,minFreeThreads,minLocalRequestFreeThreads,appRequestQueueLimit,enableVersionHeader)"/>
<httpRuntime enableVersionHeader="false" maxRequestLength="12288" xdt:Transform="SetAttributes"/>
<customErrors mode="On" xdt:Transform="SetAttributes"/>
What is the best way to update these attributes during release?
Both Web Deploy's parameters.xml method and transforms can be used with Release Management. Transforms would be triggered from Build and the process of replacing tokens created by a publish would be triggered by Release Management.
To trigger transforms during the build, you can do this one of two ways:
Add the following MSBuild parameters to force the transformation to happen during the build
/p:UseWPP_CopyWebApplication=true /p:PipelineDependsOnBuild=false
Create a publish profile using the MSDeploy Package option and then trigger the packaging in Build using the following MSBuild parameters:
/p:DeployOnBuild=true /p:PublishProfile=[nameOfProfile]
Either of the above methods will cause normal Web.config XDT's to run. If you need other XML files to be transformed, you'll need to first install SlowCheetah.
Token Replace and Parameters
Now that you have a build artifact with XDT's run, you can use token replacement and the WinRM tasks from Release Management. These will take the Web Deploy package from the Build and execute the SetParameters command before deploying it. The trick is to take the SetParameters.xml file and run a token replace on it first, swapping out Release environment variables first.
User Sumo gave a proper answer, but I want to record some comments related to what instead of how.
IMHO there are different categories of settings to consider, let's exemplify. The database connection string changes at each environment, while requiring SSL should be turned on for all testing and production environments.
In this perspective, you should have settings applied as early as possible, traditionally at build time and called Debug/Release builds; and last-minute settings, environment dependent, up to runtime settings, like Feature toggles.
So in my view you can use a single tool or multiple tools, but it is important that you properly categorize your settings accordingly.

How to differentiate TFS Builds and manual builds using macros in Post build event

In TFS post build script of a .proj file I want to find whether the project build is happening through TFS triggered build or manually triggered build.
Can someone suggest me how to do this using macros in Post Build event.
Short answer: you can make use of the IsDesktopBuild MSBUILD property within your csproj file to differentiate between TFS and local build.
Long Answer:
Developer or Team Build?
To differentiate the build environments we have to implement a mechanism that detects in which environment the build is being executed. In other words, we need to know if we running a local build that is executed by the developer or a team build running on the build server.
In fact, there are 3 different build environments we need to consider:
· Visual Studio Build – a build executed by a developer, on their own development machine inside the Visual Studio IDE
· Team Build – a build executed by TFS (manually or scheduled), on the build.
· Desktop Build – a build explicitly executed manually, on the development workstation using the command 'msbuild.exe tfsbuild.proj'.
A ‘DesktopBuild’ and a ‘TeamBuild’ are very similar in nature except that ‘DesktopBuild’ does not perform a ‘GetLatest’ function from source repository, will not ‘Label’ the source tree and will not determine the change set.
When using MSBUILD tasks (as we will use primarily in following sections), one common way to achieve this is to use the ‘IsDesktopBuild’ and ‘BuildingSolutionFile’ properties as conditions to test in the tasks.The ‘IsDesktopBuild’ property is declared in the ‘Microsoft.TeamFoundationBuild.targets’. The ‘BuildingSolutionFile’ property is declared and assigned automatically by MSBUILD.
The following table lists the values of each of these properties in each of the build environments.
Environment IsDesktopBuild BuildingSolutionFile
Visual Studio Build (empty) (empty)
Desktop Build true true
Team Build false true
One caveat with using the ‘IsDesktopBuild’ property is that it is not defined in many target files by default. This property will have an ‘empty’ value in a Visual Studio build, so we initialize it to a value of ‘true’ as the default value. Therefore we need to be explicitly define it in all MSBUILD target files where it will be tested.
We simply add the following element to all target files where we need to differentiate between a build on the development machine and a build on the build server (within the first section).
<IsDesktopBuild Condition="'$(IsDesktopBuild)' == ''">true</IsDesktopBuild>
Update: thank you #dbardakov. Starting VS 2012 we can use the property to find if the build is happening within Visual Studio:
BuildingInsideVisualStudio
MSDN SOURCE - for BuildingInsideVisualStudio
MSDN SOURCE

Deploy website to drop folder on TFS build server

I am using TFS 2012 on a build server to do continuous integration, and also builds for other environments. I am deploying a .net 4.0 webforms solution containing two websites and a console app to a build server and in the drop folder I get a _PublishedWebsites folder containing the deployment package for the custom configuration I have specified (ie not Debug or Release). I get the correct .Web_Package for each website.
I am using the MSBuildArgumments setting in the build process as follows:
/p:DeployOnBuild=true /p:PublishProfile=Development/p:VisualStudioVersion=10.0
Everything works well, but the team lead wants the actual deployment in the drop-folder and not the deployment package.
I have looked at the MS Documentation but it does not appear to help in my case.
I have tried creating a script, but I dont want to go into a huge series of powershell scripts, and I struggle with powershell anyway. I just cant get it to do what I want.
My question is: can this be done, and what is the best way of doing it? If it does mean creating a script then so be it ( perhaps one line for each object) - I am really having a hard time working out which direction I should be going in.
I thought something a script containing one line for each deployment -3 lines like this:
_PublishedWebsites/<project name>.Web_Package/<project name>.deploy.cmd /T: /M:<site> /U:<user> /P:<password>
But where to put the script and how to call?
I ended up using the solution as described in this blog post:
http://blog.degree.no/2012/03/automatic-config-transformations/
To get what I needed, I needed to change the project files of the projects to be deployed - adding this extra node at the top of each.csproj file
<Target Name="TransformConfigFiles" AfterTargets="AfterBuild" Condition="'$(TransformConfigFiles)'=='true'">
<ItemGroup>
<DeleteAfterBuild Include="$(WebProjectOutputDir)\Web.*.config" />
</ItemGroup>
<TransformXml Source="Web.config" Transform="$(ProjectConfigTransformFileName)" Destination="$(WebProjectOutputDir)\Web.config" />
<Delete Files="#(DeleteAfterBuild)" />
</Target>
and adding this switch to the MSBuildArguments in the build definition:
/p:TransformConfigFiles=true
When I run my builds using the DeployOnBuild switch, my builds output two folders, one with the Package, and one with just all the website files (both under PublishedWebsites). Is that not what you want?
I have:
BuildDrop_PublishedWebsites\Website
BuildDrop_PublishedWebsites\Website_Package

SpecFlow wrongly using NUnit

I've just (today) tried SpecFlow for the first time. I'm playing about by creating a new class library in VS2010 Pro and adding a SpecFlow Feature Definition file.
Thing is, the integration doesn't appear to be working properly, with a variety of different errors. I've selected MsTest as the test runner, because I can't be bothered with invoking NUnit (I'd like to use NUnit in the long term but at the moment I just want to get some BDD code working). The generated code files however continue to reference NUnit - which is obviously wrong, since I've just told SpecFlow to run using MsTest. I've done everything I can think of to invoke the code generation again, including creating a brand new class library project with the MsTest option selected in Tools > Options > SpecFlow.
If I leave the test runner field set to 'Auto' and right-click a feature file, then select 'Run SpecFlow Scenarios' I get an error message "Could not find matching test runner".
If I instead change the test runner field to MsTest, I get a different error message on doing the same thing - "Object Reference not set to an instance of an object". I'm not surprised at this one since it's still trying to run NUnit tests even though I've explicitly asked for MsTest, though obviously it shouldn't nullref and present that to the user.
What am I doing wrong? The documentation is not helpful, and as far as I can see, there's no FAQ.
edit #1: I've established that the actual setting I'm looking for is provided using App.Config using the field <unitTestProvider name="MsTest" />. I can see what's happened - the field in the Visual Studio options menu doesn't seem to modify the project you're currently working on. Thing is, this makes it look like that field doesn't do anything at all. I've now persuaded SpecFlow to generate MsTest classes and run using the MSTest runner.
So now the question morphs into a slightly different one: What (if anything) does the Tools > Options > SpecFlow > Test Runner Tool field do?
With VS2010 the correct value is MsTest.2010 not MsTest as documented. Change your app.config (for the test assembly) and it will work fine (at least with SpecFlow 1.8)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="specFlow" type="TechTalk.SpecFlow.Configuration.ConfigurationSectionHandler, TechTalk.SpecFlow" />
</configSections>
<specFlow>
<unitTestProvider name="MsTest.2010" />
<!-- For additional details on SpecFlow configuration options see https://github.com/techtalk/SpecFlow/wiki/Configuration -->
</specFlow>
</configuration>
In answer to your latest Question. What is the setting "Tools > Options > SpecFlow > Test Runner Tool" this setting controls what will actually run the tests, not what will generate the test code. If it is set to auto i believe it will look at the App.config file where you have set the unitTestProvider to determine what the best tool is to run the tests. An alternaive Test runner made by the same guys as SpecFlow is SpecRun http://www.specrun.com/
So when you go to run the tests it will use this option. As you have discovered though the code generator uses the config file to determine what type of test it should generate (mstest/nunit..)
If you ran the specfow installer ( https://github.com/downloads/techtalk/SpecFlow/SpecFlowSetup_v1.8.1.msi ) to install all the Visual Studio Intergration components when you change the App.config file it normally promps to regenerate the features using the new provider. The manual way to do this though is to right click the Feature and select "Run Custom Tool"
In regards to documentation have you found the git hub wiki?
https://github.com/techtalk/SpecFlow/wiki/Documentation
The way I've read this is that the test runner is entirely different to that of the code generator although that doesn't always make sense when the MsTest runner doesn't know about NUnit (I think). Out of the box, the latest version (v2.3.2) even when installed with SpecFlow.MsTest nuget package (of the same version) does not configure your machine to generate MsTest based classes in the background. I am running VS2017 and have Resharper installed as my 'test runner' but the main requirement for generating MsTest based code is a change to the app.config. As per the wiki documentation you also need the following in your app.config. When you save the config you should be prompted for the files to be regenerated.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="specFlow"
type="TechTalk.SpecFlow.Configuration.ConfigurationSectionHandler, TechTalk.SpecFlow"/>
</configSections>
<specFlow>
<unitTestProvider name="MsTest" />
</specFlow>
</configuration>
We are using ReSharper as a runner for SpecFlow acceptance tests; it worked well right out of the box. Although ReSharper is not free, but it worth every penny...
I was never able to get SpecFlow working right from Visual Studio, I spent some time working on it but never go anywhere. Though I found these instructions on setting up NUnit in Visual Studio 2010 and I use this shortcut to run my SpecFlow tests with good effect.
Overall we use PowerShell to run a lot of tests and I was able to incorporate the NUnit command line runner and SpecFlow report generator into a single script I can run easily.