How to use MSBuild with TFS and SSIS - tfs

I'm a complete novice in using TFS Build definition and MSBuild scripts.
I want to automate my SSIS build and deployments and create a build definition which will build and deploy my SSIS project whenever I queue it up.
I found this project: http://sqlsrvintegrationsrv.codeplex.com/releases/view/82369
which allows you to create a DLL which you can place in C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies
Then you can call the SSIS.MSBuild.proj (See end for this) with certain parameters like this in a visual studio command line:
MSBuild SSIS.MSBuild.proj /t:SSISBuild,SSISDeploy /p:SSISProj="MySSISProject",Configuration="DEV",,SSISServer="AB-CDE-FGH-I1\DEV",ProjectName="MySSISProject"
or I can put it in a BAT file like this:
%systemroot%\Microsoft.Net\Framework\v4.0.30319\MSBuild.exe SSIS.MSBuild.proj /t:SSISBuild,SSISDeploy /p:SSISProj="MySSISProject",Configuration="DEV",,SSISServer="AB-CDE-FGH-I1\DEV",ProjectName="MySSISProject"
It works fine when you run the BAT file, it builds and deploys the SSIS project.
Questions:
How can I use this so it is automated, so I can manually kick off a build and deployment from within VS/TFS? Using a build definition.
How can I ensure the correct configurations are selected, and the correct destination server? For example we have SSIS configurations for DEV, SIT, SYS, UAT, PRD. Each with its own server name. Do I need a separate build definition for each environment or is there a way to use one build definition?
Anything useful in using powershell somehow?
Here is SSIS.MSBuild.proj:
<?xml version="1.0" encoding="Windows-1252"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
DefaultTargets="SSISBuild;SSISDeploy">
<!--Requires a property called $(SSISProj) to be defined when this script is called-->
<UsingTask TaskName="DeploymentFileCompilerTask" AssemblyFile="C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies\Microsoft.SqlServer.IntegrationServices.Build.dll" />
<Target Name="SSISBuild" Condition="'$(SSISProj)' != ''">
<PropertyGroup>
<SSISProjPath>$(SSISProj)\$(SSISProj).dtproj</SSISProjPath>
</PropertyGroup>
<Message Text="**************Building SSIS project: $(SSISProjPath) for configuration: $(CONFIGURATION)**************" />
<DeploymentFileCompilerTask
InputProject="$(SSISProjPath)"
Configuration="$(CONFIGURATION)"
ProtectionLevel="DontSaveSensitive">
</DeploymentFileCompilerTask>
</Target>
<UsingTask TaskName="DeployProjectToCatalogTask" AssemblyFile="C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies\Microsoft.SqlServer.IntegrationServices.Build.dll" />
<Target Name="SSISDeploy" Condition="'$(SSISProj)' != ''">
<Message Text="**************Publishing SSIS project: $(SSISProj) to: $(SSISServer) to folder: $(PROJECTNAME)**************" />
<PropertyGroup>
<ISPac>$(SSISProj)\bin\$(CONFIGURATION)\$(SSISProj).ispac</ISPac>
</PropertyGroup>
<DeployProjectToCatalogTask
DeploymentFile="$(ISPac)"
Instance="$(SSISServer)"
Folder="$(PROJECTNAME)"
CreateFolder="true"/>
</Target>
</Project>
EDIT I tried adding some MSBuild Arguments to the TFS Build Definition. I tried various combinations of arguments, some with quotes, some without. I couldn't get it to work.
"C:\Users\me\Desktop\Buildssis\SSIS.MSBuild.proj" /t:SSISBuild,SSISDeploy /p:SSISProj="MySSISProject",Configuration="SIT",SSISServer="AB-CDE-FGH-I1\DEV",ProjectName="MySSISProject"
But I always get this error:
MSBUILD : error MSB1008: Only one project can be specified.
Switch: C:\Users\me\Desktop\Buildssis\SSIS.MSBuild.proj
For switch syntax, type "MSBuild /help"

I think you are prety close about the solution. you can call your package in console application and set the variables there. And for different DEV, SIT, SYS, UAT, PRD. you can have configuration file for the the console application. and then you can set the package variables in the console app. I hope it solve the preoblem. As much i could understand.
Please let me know if this is not related to your problem then explain your question a bit more.

To answer your question, the best way would be to use an UpgradeBuildTemplate for your team build.
Modify the build script to calls the tasks that you have created in the "AfterCompile" target of the build. See below
http://msdn.microsoft.com/en-us/library/aa337604(v=vs.100).aspx
You can pass build parameters in your team build definition. If you edit your build definition and edit Process, you will see option to pass MSBuild Arguments.

Related

Buildiling .net multiple Solutions in Jenkins using MSBuild plugin

I am trying to build .net multiple Solutions files in Jenkins using MSBuild plugin. I have installed and configured MSBuild. In the Build step - 'Build a Visual Studio project or Solution using MSBuild', under 'MSBuild Build FIle' how do we reference the build file(ex, test.txt) which have 5 solution file paths in it. When i give the path directly C:\test.txt, the build is failing with error
C:\test.txt(1,1): error MSB4025: The project file could not be loaded. Data at the root level is invalid. Line 1, position 1.
0 Warning(s)
1 Error(s)
Time Elapsed 00:00:02.22
Build step 'Build a Visual Studio project or solution using MSBuild' marked build as failure
Finished: FAILURE
Below are the solution file paths mentioned in my test.txt file
C:\workspace\DotNet\Constants.sln
C:\workspace\DotNet\Security.sln
C:\workspace\DotNet\Library.sln
C:\workspace\DotNet\Mapping.sln
C:\workspace\DotNet\MapForce.sln
Could I build by mentioning five solution file paths in .txt file and referring the .txt file path by just using one 'Build a Visual Studio project or solution using MSBuild section'?
I have tried with command prompt manually it builds fine. Also, tried with 'Execute Windows batch command' option by batch commands it works fine and builds successfully, facing problem with 'Build a Visual Studio project or solution using MSBuild' when spefiying .txt file which has many solution file paths in it.
Appreciate your help on this.
MSBuild builds MSBuild files, written in xml, not text files (hence the error MSB4025). Luckily creating a file which can be used to build x other files is fairly simple, here is an example:
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<ItemGroup>
<Sln Include="C:\workspace\DotNet\Constants.sln"/>
<Sln Include="C:\workspace\DotNet\Security.sln"/>
<Sln Include="C:\workspace\DotNet\Library.sln"/>
<Sln Include="C:\workspace\DotNet\Mapping.sln"/>
<Sln Include="C:\workspace\DotNet\MapForce.sln"/>
</ItemGroup>
<Target Name="Build">
<MsBuild Projects="#(Sln)" Targets="Build" Properties="Configuration=Release;Platform=Win32" BuildInParallel="True" />
</Target>
</Project>
This is just written in a straightforward way, shorter but possibly more complicated code might apply. E.g. to just build all solutions in the C:\workspace\DotNet directory you'd just write <Sln Include="C:\workspace\DotNet\*.sln"/> instead of manually spelling out each of them. Or if all of them reside in that directory you could include them by filename only, e.g. <Sln Include="Constants.sln"/> and then add the directory when expanding the list like Projects="#(Sln->'c:\workspace\dotnet\%(Identity)')".
As you can see this builds the Win32|Release version, change that by altering the properties. Also not the BuildInParallel switch: only use this if the solutions don't depend on each other.

How to generate document output from text files in TFS

We store various design documents within TFS in multimarkdown format. We also have an EXE process that can run to take those MMD files and generate PDF's from them - but just by getting the files from a local folder.
What we'd like to do is to have a process run "on-checkin", just as if you'd run an automatic build on checkin (i.e., ultimately calling msbuild to compile an application) but in our case we'd like it to be able to get a list of the checked in files and to process and generate an output of them. The result doesn't need to be in TFS because they're a build output, not the source.
I'm sure this should be somehow possible by taking the same approach as must be taken by the workflow for a "normal" build.
Has anybody done anything like this or can point me in a suitable direction please ?
You could use the exec task in MSBuild to invoke the exe and "build" your output. Create a file called something like buildDocs.proj and check it in to TFS possibly in a folder under the things you want to build. Use the MSbuild below as a guide.
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Build">
<Exec Command='"My.exe" -My Paramiters' />
<ItemGroup>
<CopyItems Include="[path to output]\*.*" />
</ItemGroup>
<Copy SourceFiles="#(CopyItems)" DestinationFolder="$(OutDir)\SomeDir" />
</Target>
</Project>
The trick will be in identifying the various paths involved.
Use the default template to build the proj, just as you would a c# project. If you need to pass in additional Parameters to MSBuild you can do this from within the advanced section of the build definition process tab.

Executing Visual Studio from Team Foundation Server

I am working on a project to convert a large application (Database, SSIS packages, some class libraries, PowerShell scripts) from building using a batch file to TFS build and possibly deploy. Currently, how the process works is that a Batch file is ran, and some inputs are taken in, which get stored as variables (environment which helps determine which build to kick off), than MSBuild is called, like so
MSBUILD BuildAll.proj /t:Clean,Build,Package /p:Configuration=%CONFIGURATION% /fl /flp:Summary;LogFile=%LOGFILE% /fl1 /flp1:ErrorsOnly;LogFile=%ERRORLOGFILE% /tv:4.0
The BuildAll.proj is a custom project file that sets some variables, but most importantly (and the part that is failing) executes a command to call Visual Studio to build the solution
<Target Name="Build">
<Exec Condition=" '%(Application.Solution)' != '' " Command='"$(DevEnv10InstallDir)Devenv.com" %(Application.Solution) /Rebuild $(Configuration)' />
</Target>
Here is the log that gets built out
Target "Build" in project "C:\Source\MBFinancial\Development\Trunk\Source\BuildAll.proj" (entry point):
Using "Exec" task from assembly "Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
Task "Exec"
"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Devenv.com" Application.sln /Rebuild LocalDevelopment
When I look at the Build Events, it just hangs there, and the Build Folder on the TFS server is never populated as it should. The build process runs just fine if I run it from the TFS server, running as the TFS Build Account, so I know all the proper installs are on the Build Server, but when I execute through Visual Studio Team Explorer, it hangs. I can provide additional details if needed.
you can add a /out switch to devenv.exe (pretty sure you can to devenv.com too), I think you're only looking at teambuild's output and not devenv's, which hopefully will shed light on what's up.
FWIW here's my exec task:
<Exec WorkingDirectory="$(MSBuildProjectDirectory)\Xxx" Command='"$(VS2010)"\devenv.exe xxx.sln /REBUILD "$(Configuration)|x86" /OUT $(MakeLog) /LOG C:\tmp\ActivityLog.xml' ContinueOnError="false" />
I can't remember why I use .exe and an outfile rather than .com.

Running a build against multiple projects with different build arguments

I have a series of projects that need to be compiled and published, deployed to separate directories with separate MSBuild arguments. As it stands, I have separate builds for each. For example, project 1:
MSBuild Arguments: /target:myTarget /property:PublishDir=\\1.1.1.1\PublishDir1
and project 2:
MSBuild Arguments: /target:myTarget /property:PublishDir=\\1.1.1.2\PublishDir2
However I'd like to merge them into a single build. The problem I have is that although TFS will allow me to specify multiple projects in the build, the MSBuild arguments apply to all projects. Is there a quick way I can force a distinct set of build arguments per project, or do I need to create a new build template to do this?
I am afraid, you need new build template to pass additional arguments to the template.
But if you are trying to Publish the build output to different directory based on different Project, you can achieve it by setting up same publish profile for each project. Add publish profile for each Project with same name. you can use File system Publish Method to Publish the output to different directories for each project. Just call the Publish profile in the MsBuild Argument.
/p:DeployOnBuild=true;PublishProfile=Dev
I suggest, that you create an MSBuild .proj file to execute the builds, i.e.:
<Project ToolsVersion="4.0" DefaultTargets="Rebuild" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Rebuild" >
<!--Execute proj1-->
<MSBuild Projects="Proj1.csproj" Properties="Configuration=Debug;PublishDir=\\1.1.1.2\PublishDir1;></MSBuild>
<!--Execute proj2-->
<MSBuild Projects="Proj2.csproj" Properties="Configuration=Debug;PublishDir=\\1.1.1.2\PublishDir2;></MSBuild>
</Target>
</Project>
Just point your tfs to this custom .proj file.

TFS Build Error While Invoking custom build file via TFS Build definition

I use TFS 2010, VS 2010.
I wrote a custom msbuild proj file which I use locally to build my solution. I use MSBUILD.exe TFSBuild.proj and it does everything in my local machine. (I have a taregt called 'DoMyBuild' which kicks off the build and does everything.)
I have used this in the DefaultTargets attribute as below:
<Project DefaultTargets="DoMyBuild" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
I am trying hard to configure this to use my build server with a build definition. In the build definition, under Process - I configured 'Upgrade Template' and in the build process paramters, have given the path to this TFSBuild.Proj file.
Ideally. TFS should start 'DoMyBuild' target as I read. But it gives a error looking for 'EndToEndIteration' not defined. So, I believe it is still doing a DesktopBuild which I dont want. I want to use my custom target to kick start. Is this possible ?
Any help is very much appreciated.
Thanks, Mani
You problem is discussed here.
Make sure you have at least an EndToEndIteration target defined in your MSBuild project.
<Target Name="EndToEndIteration"
Condition=" '$(IsDesktopBuild)'!='true' "
DependsOnTargets="$(EndToEndIterationDependsOn)" />

Resources