Running rsvars.bat before Teamcity build starts - msbuild

I have a C++ Builder 2010 project that's being built using TeamCity. I noticed some strange errors and after reading up on them I understand that I have to set a few variables located in rsvars.bat. I would like the build script to execute the bat file to set up the environment before performing the actual build. How do I best accomplish this?
Can I just use a <exec /> command at the very beginning of the file or is there a better way?

One way would be to run wrap the build in a script that calls rsvars.bat AND build commands. That would make the variables survive during the execution of the build.
But since I use TeamCity I like it to be a real msbuild step and not msbuild wrapped in something else. I was thinking of having the buildscript setting the variables from rsvars.bat into Machine or User at the start of the build and then remove them at the end, not nice though.
I finally just went with just adding the configurations to the Build Agents environment configuration in TeamCity and keeping installation paths identical between agents.

You can create a new build step and then specify a custom build step order so a new build step will be the first one.
See Configuring Build Steps

Add them as Build Parameters -> Environment Variables (in the build configuration), straight forward and generally works. The build parameter/environment variables will be setup automatically as environment variables on the build agent running the job.
You can then make a template of the build and reuse it.
Assumes that the 'paths' are the same on all build agents, which is generally the case. If not your suggestion of doing it by build agent is the way to go.

Related

MSBuild - Can I build for a Build Configuration without a solution?

I want to build a project with a particular named Build Configuration, let's call it Conf-A.
This is running as an MSBuild step on TeamCity. When the build runs, it spits out:
The OutputPath property is not set for project ... You may be seeing this message because you are trying to build a project without a solution file, and have specified a non-default Configuration or Platform that doesn't exist for this project.
This project is part of a hulking great solution we load on our dev machines.
The error makes sense for my situation, since I'm building just the proj file, but I don't want to use the solution file since I'm trying break-up this monolithic app.
I want the build-server to treat this project as it's own component, even if for the moment it is part of a solution and has references to other projects (assemblies) in the solution.
Must I build this via a solution file?
I could potentially copy the solution file and prune off all the other projects that are not required, but that's more complexity.
(Maybe the error is a red-herring).
you dont need to build a sln. Its like the error says. You just havent specified a value for the variable OutputPath in your msbuild. You can add it to your files or you can pass it in at the cmd line - msbuild someproj.proj /p:OutputPath=C:\notallovermydrive

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

Integrate psake with MsBuild

I am using MSBuild for CI. I was looking recently to psake as an additional tool for creating scripts for daily builds as I need to do some updates to our builds which will be easier in psake. For the moment I’m not looking to replace our existing scripts as it requires a lot of work but keep the existing ones and add new using psake.
My question is - when I create a build in TFS how can I run the psake scripts after the solution is built? My understanding is that I need to add a new target after the build is executed and execute the psake/powershell. Is this the right way to do it?
Yes that is how you would do it. It is best to separate different parts of your build script so that if you want to change something, you can proceed with ease.
So, Ideally, you should have a task for compiling your solution, another for running the tests, another for packaging the source and so on ... I recently started using psake, and this is a good reference in case you want to look up something.
The right way to do this is to use TeamCity to run your psake build scripts. In your psake scripts you would create a psake Task that calls msbuild via exec { msbuild yourSolution.sln }.

Using a variable obtained using a pre-build shell command to set an option for the Maven build in Hudson

I have a Hudson job that runs a maven goal. Before this maven goal is executed I have added a step to run before the build starts, it is a shell script that obtains the version number that I want to use in the 'Goals and options' field.
So in my job configuration, under Build Environment I have checked the Configure M2 Extra Build Steps box and added a shell script before the build. The script looks like this:
export RELEASE={command to extract release version}
echo $RELEASE
And then under the Build section I point to my 'root pom'. In the Goals and options I then want to be able to do something like this:
-Dbuild.release.version=${RELEASE} deploy
Where build.release.version is a maven property referenced in the POM. However since the shell doesn't seem to make its variables global it doesn't work. Any ideas?
The only one I have is to install the Envfile plugin and get the shell script to write out the RELEASE property to a file and then get the plugin to read the file, but the order in which everything is run may cause problems and it seems like there must be simpler way...is there?
Thanks in advance.
I recently wanted to do the same, but AFAIK it's not possible to export values from a pre-build shell to the job environment. If there is a Hudson Plugin for this I've missed it.
What did work, however, was a setup similar to what you were suggesting: having the pre-build shell script write the desired value(s) to a property-file in the workspace, and then using the Parametrized Trigger Plugin to trigger another job that actually does the work (in your case, invoke the Maven job). The plugin can be configured to read the parameters it passes from the property file. So the first job has just the shell script and the post-build triggers, and the second one does the actual work, having the correct parameters available as environment variables.
General idea of the shell script:
echo "foo=bar
baz=`somecmd`" > build.properties
And for your Goals and options, something like:
-Dbuild.release.version=${foo} deploy
Granted, this isn't as elegant as one might want but worked really well for us, since our build was broken into several jobs to begin with, and we can actually reuse the other jobs that the first one triggers (that is, invoke them with different parameters).
When you say it doesn't work, do you mean that your RELEASE variable is not passed to the maven command? I believe the problem is that by default, each line of the shell script is executed separately, so environment variables get lost.
If you want the entire shell script to execute as if it was one script file, make the first line:
#!/bin/sh
I think this is described in the Help information alongside the shell script build step (and if I'm wrong, that's a good place to look for the right syntax).

How to create a TFS2010 Team Build Template for getting source and call msbuild.exe

I have a build.proj, that is a MSBuild file and can be run locally.
All I need from TFS is
Get the sources from TFS Source Control.
Call "MSBuild.exe /t:Deploy".
Update the build status based on the result of MSBuild.
I have tried to make a template combining the DefaultTemplate.xaml and UpgradeTemplate.xaml.
But so far, no luck :-(
Can someone help me make this template?
If you select the upgrade template that comes out of the box when you create a new TFS project with 2010, you can supply your old TFS2008 proj (MSBuild) file without problems. Please read http://msdn.microsoft.com/en-us/library/dd647553.aspx for more details.
You should use DefaultTemplate. I had the same problem and I solved it this way.
You can do it using UpgradeTempate also, but using DefaultTemplate was easier for me.
On Process section follow these steps:
Select Default template
Add your project into Items To Build collection
Set MSBuild Arguments (Advanced section) to "/t:Deploy"
I have MSBuild project file for running builds locally. This script is used also for sever builds. I have three MSBuild projects in Items To Build collection. One for PreBuild step (some checks before build is executed), main build script used also for local build and the last script for additional post build tasks (deploy process). I'm setting additional MSBuild propertires like IncrementalBuild and ServerBuild properties in MSBuild Arguments.