How to use StyleCop with TeamCity - teamcity

Has anyone had any success with running StyleCop from TeamCity?
I know StyleCop supports a command line mode, however i am not sure how this will integrate into the report output by TeamCity.
I've checked out this plugin found here: https://bitbucket.org/metaman/teamcitydotnetcontrib/src/753712db5df7/stylecop/
However could not get it running.
I am using TeamCity 6.5.1 (latest).

I don't know how familiar you are with MSBuild, but you should be able to add a new Build Step in TC 6 and above, and set MSBuild as the build runner, and point it to a .proj file which does something similar to the following:
<Target Name="StyleCop">
<!-- Create a collection of files to scan -->
<CreateItem Include="$(SourceFolder)\**\*.cs">
<Output TaskParameter="Include" ItemName="StyleCopFiles" />
</CreateItem>
<StyleCopTask
ProjectFullPath="$(MSBuildProjectFile)"
SourceFiles="#(StyleCopFiles)"
ForceFullAnalysis="true"
TreatErrorsAsWarnings="true"
OutputFile="StyleCopReport.xml"
CacheResults="true" />
<Xslt Inputs="StyleCopReport.xml"
RootTag="StyleCopViolations"
Xsl="tools\StyleCop\StyleCopReport.xsl"
Output="StyleCopReport.html" />
<XmlRead XPath="count(//Violation)" XmlFileName="StyleCopReport.xml">
<Output TaskParameter="Value" PropertyName="StyleCopViolations" />
</XmlRead>
<Error Condition="$(StyleCopViolations) > 0" Text="StyleCop found $(StyleCopViolations) broken rules!" />
</Target>
If you don't want to fail the build on a StyleCop error, then set the Error task to be Warning instead.
You'll also need to add the following to your .proj file:
<UsingTask TaskName="StyleCopTask" AssemblyFile="$(StyleCopTasksPath)\Microsoft.StyleCop.dll" />
Microsoft.StyleCop.dll is included in the StyleCop installation, and you'll need to set your paths appropriately.
To see the outputted StyleCop results in TeamCity, you will need to transform the .xml StyleCop report to HTML using an appropriate .xsl file (called StyleCopReport.xsl in the script above).
To display the HTML file in TeamCity, you'll need to create an artifact from this .html output, and then include that artifact in the build results.
The Continuous Integration in .NET book is a great resource.

Did you know that teamcity provides specific properties just from msbuild?
No need for the service messages, see:
http://confluence.jetbrains.net/display/TCD65/MSBuild+Service+Tasks
So you dont have to add a custom report page.
Use the build stats e.g.
<TeamCitySetStatus Status="$(AllPassed)" Text="Violations: $(StyleCopViolations)" />
you can then log the statistic too:
<TeamCityReportStatsValue Key="StyleCopViolations" Value="$(StyleCopViolations)" />
And then create a custom graph to display, and you already have the violations in your msbuild output.
edit main-config.xml and add:
<graph title="Style Violations" seriesTitle="Warning">
<valueType key="StyleCopViolations" title="Violations" buildTypeId="bt20"/>
</graph>
Where buildTypeId="bt20" bt20 is your style build.

I'm late to the show here but a very easy way to achieve this is to install the StyleCop.MSBuild NuGet package in any project which you want to analyse with StyleCop.
After installing the package, StyleCop analysis will run on every build you do, regardless of where or how it is invoked, e.g VS, command line, msbuild, psake, rake, fake, bake, nant, build server, etc. No special actions are required.
If you want the build to fail when StyleCop rules are broken you just need to add the following element to your project file under each appropriate build configuration, E.g.
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<StyleCopTreatErrorsAsWarnings>false</StyleCopTreatErrorsAsWarnings>
...
Again, this will work on every build, regardless of where and how it is invoked.

There's a (new?) third-party TeamCity plugin for StyleCop here, (though I haven't tried it yet).
UPDATE: as far as I can tell, the latest version only works with TeamCity 7 (or I did something wrong). Also, I have a very slow (virtual) build server, so even after the services were restarted, it took a while for the StyleCop runner to appear in the web interface.
Another stupid thing I did was not read the readme properly: you have to unzip the downloaded zip, and use the zip inside.
I also originally started with just a list of .cs files in the "Include" option (for the build step), but that didn't work; links to sln or csproj files do work though.

Related

TFS build deploy is failing

My solution has 5 projects and tfs build is working fine. Issue I am having is when I set to deploy from tfs on successful build. Its looking for publish profile in wrong project rather than my startup project. Please Help.
ScreenShot
Update:- So I was able to eventually find what was causing the issue during my build and publish in tfs. Each of the projects that were added in my solution were web applications. And Each of the project had in .csproj file these settings <Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
</Target>. Once I have commented out these in my other applications, the tfs build/publish using my publish profile was not looking for config file that I mentioned in my publish profile. Thanks for your help Patrick.
Suggest you first manually remote to your build agent and double check if there are corresponding DEVAPP1DEBUG.‌​pubxml file located at the path on the build agent.
According to your description, maybe there are something wrong in your build artifacts for deployment. Suggest you try this way, looking into the TFS options for Build Definitions and when you have to select a template for the definition, you can see two options Build and Deployment, try with the Deployment option :
and by default in the MSBuild Arguments the parameter is :/p:OutDir="$(build.binariesdirectory)\\"
In that folder you should have everything need for the deployment.

Sequentially build configurations in Visual Studio without MSBuild or plugins?

MSDN describes how to create a batch build, but does not provide a way to automate different batches (and one click solution for the GUI)
This question describes conditionally invoking a second build but doesn't appear to suffice for more than two sequential configurations
This question addresses the same situation, but again only for two configurations
In my test case, each configuration:
defines its own MACROS (which impact source code)
is applicable to multiple projects (class libraries). The projects are interdependent and require a specific build order in the context of the current configuration
I would like visual studio to build multiple configurations sequentially with a single build command.
Can child configurations be nested under a parent configuration, and be executed sequentially by visual studio when the parent configuration is built?
UPDATE : ATTEMPTED SOLUTION 1 [2016-03-11]
In response to Stijn's suggested answer I've tried the following:
Setup DotNetFramework 4.5 WinForms solution with 3 test projects and with 6 Configurations:
CORE_DEBUG
CORE_RELEASE
EXTENDED_DEBUG
EXTENDED_RELEASE
Debug
Release
The Debug Configuration must:
NOT trigger it's own configuration build (i.e. 'Debug')
must trigger the CORE_DEBUG and EXTENDED_DEBUG Configurations in sequence
I've added the following modified target to the first project's project file:
<Target Name="AfterBuild" Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
Building with the 'Debug' Configuration now, causes an EXTENDED_RELEASE build to trigger. Having a look at the solution file, I see that Visual Studio decided to automatically link 'Debug' to 'EXTENDED_RELEASE':
{4F9706AA-26A9-483C-81C4-22E301C54C89}.Debug|Any CPU.ActiveCfg = EXTENDED_RELEASE|Any CPU
{4F9706AA-26A9-483C-81C4-22E301C54C89}.Debug|Any CPU.Build.0 = EXTENDED_RELEASE|Any CPU
Removing the above two lines from the solution file doesn't help, since Visual Studio just regenerates them. In summary this now has two undesirable outcomes:
Visual Studio executes a 'Debug' build for Project1
Visual Studio then executes an 'EXTENDED_RELEASE' for Project2 and Project3
Conclusion: While this approach can work, it also (first) performs debug and release configuration builds respectively. Visual Studio
also lists all 6 Configurations in the build menu (we only want Debug
and Release to be visible, and behind the scenes Debug must trigger
CORE_DEBUG and EXTENDED_DEBUG, and Release must trigger CORE_RELEASE
and EXTENDED_RELEASE)
UPDATE : ATTEMPTED SOLUTION 2 [2016-03-16]
Moving on to a makefile project solution: I've created a makefile project as specified by stijn's answer below, and it worked perfectly!
Conclusion : This is the preferred solution in my opinion because it gives the user the most power and ability to control exactly how the build(s) must be executed and how the configurations must be handled.
The principle of the second SO question can be adjusted to build more than one configuration/platform sequentially by just invoking MsBuild multiple times. For instance:
<Target Name="AfterBuild" Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<MSBuild Projects="$(MySolution)" Properties="Configuration=Release;Platform=x86"/>
<MSBuild Projects="$(MySolution)" Properties="Configuration=Debug;Platform=x64"/>
<MSBuild Projects="$(MySolution)" Properties="Configuration=Release;Platform=x64"/>
</Target>
This can be cleaned up by using item batching, removing the condition and instead automatically determining which config is invoked and then only building the others etc but that's a bit out of scope here.
I'm not really convinced doing this in an AfterBuild target is the best way though, because then you'd need to adjust one of your 'normal' projects to also trigger a build of everything else. An alternative is to add a MakeFile Project to your solution, set up it's dependencies so that it comes last in the build order (at least if that is what you need), and set it's command line to invoke msbuild in a way similar as described above. You can even keep all logic in the same project file: set the 'Build Command Line' to
msbuild $(MsBuildThisFile) /t:CustomBuild /p:Configuration=$(Configuration);Platform=$(Platform)
so building the project will 'recurse' and make it call itself again with the same properties as called with by VS, but executing the CustomBuild target where you can then build your other projects/solutions to taste.
EDIT re: update
You're almost there, but you have to go to Configuration Manager and make sure the configurations are setup properly to begin with. From the start:
create new solution, add 3 projects
right-click solution, select Configuration Manager
in the Active solution configuration combobox select new
enter CORE_DEBUG for name, select DEBUG under Copy settings from and make sure the Create new project configurations is checked like
repeat for other configurations
for EXTENDED_RELEASE for instance, it should now look like
you probably did most of this already, but somehow Debug got assigned to EXTENDED_RELEASE somehow so that is one thing you should fix; you could do that by editing the solution manually but instead of removing lines you'd have to edit them to be correct else VS just adds them again, as you noticed
Now open first project in a text editor and near the end of the file where AfterBuild is already inserted but commented out, add
<ItemGroup>
<Configurations Condition="'$(Configuration)'=='Debug'" Include="CORE_DEBUG;EXTENDED_DEBUG" />
<Configurations Condition="'$(Configuration)'=='Release'" Include="CORE_RELEASE;EXTENDED_RELEASE" />
<Projects Include="$(SolutionDir)WindowsFormsApplication1.csproj;$(SolutionDir)WindowsFormsApplication2.csproj;$(SolutionDir)WindowsFormsApplication3.csproj" />
</ItemGroup>
<Target Name="AfterBuild" Condition="'#(Configurations)' != ''">
<Message Text="Projects=#(Projects) Configuration=%(Configurations.Identity)" />
<MSBuild Projects="#(Projects)" Targets="Build" Properties="Configuration=%(Configurations.Identity)" />
</Target>
you might need to adjust the paths to the projects. This will build CORE_DEBUG and EXTENDED_DEBUG for Debug builds, and likewise for Release builds. AfterBuild is skipped when the Configurations ItemGroup is empty, i.e. when not building Debug or Release which is exactly the point.
EDIT re: makefile
You can specify multiple commands for the makefile commandline. Click the arrow next to the 'Build Command Line' box and select '' To be sure you have everything right, Configuration Manager has to be set up to only build the makefile project for Debug/Release like:
and the makefile project's commandline looks like
Alternatively, and I'd prefer this myself, you create an msbuild file with the same content as above:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Configurations Condition="'$(Configuration)'=='Debug'" Include="CORE_DEBUG;EXTENDED_DEBUG" />
<Configurations Condition="'$(Configuration)'=='Release'" Include="CORE_RELEASE;EXTENDED_RELEASE" />
<Projects Include="$(SolutionDir)WindowsFormsApplication1.csproj;$(SolutionDir)WindowsFormsApplication2.csproj;$(SolutionDir)WindowsFormsApplication3.csproj" />
</ItemGroup>
<Target Name="Build" Condition="'#(Configurations)' != ''">
<Message Text="Projects=#(Projects) Configuration=%(Configurations.Identity)" />
<MSBuild Projects="#(Projects)" Targets="Build" Properties="Configuration=%(Configurations.Identity)" />
</Target>
</Project>
and your makefile command then invokes that file like
msbuild /path/to/msbuildfile /t:Build /p:Configuration=Debug;SolutionDir=$(SolutionDir)

VS2010 Web Publish command line version of File System deploy

Folks,
In a nutshell, I want to replicate this dialog:
It's a Visual Studio 2010 ASP.Net MVC project. If I execute this command, I get all the files I want, including the transformed web.configs in the "C:\ToDeploy" directory.
I want to replicate this on the command line so I can use it for a QA environment build.
I've seen various articles on how to do this on the command line for Remote Deploys, but I just want to do it for File System deploys.
I know I could replicate this functionality using nAnt tasks or rake scripts, but I want to do it using this mechanism so I'm not repeating myself.
I've investigated this some more, and I've found these links, but none of them solve it cleanly:
VS 2008 version, but no Web.Config transforms
Creates package, but doesn't deploy it..do I need to use MSDeploy on this package?
Deploys package after creating it above...does the UI really do this 2 step tango?
Thanks in advance!
Ok, finally figured this out.
The command line you need is:
msbuild path/to/your/webdirectory/YourWeb.csproj /p:Configuration=Debug;DeployOnBuild=True;PackageAsSingleFile=False
You can change where the project outputs to by adding a property of outdir=c:\wherever\ in the /p: section.
This will create the output at:
path/to/your/webdirectory/obj/Debug/Package/PackageTmp/
You can then copy those files from the above directory using whatever method you'd like.
I've got this all working as a ruby rake task using Albacore. I am trying to get it all done so I can actually put it as a contribution to the project. But if anyone wants the code before that, let me know.
Another wrinkle I found was that it was putting in Tokenized Parameters into the Web.config. If you don't need that feature, make sure you add:
/p:AutoParameterizationWebConfigConnectionStrings=false
I thought I'd post a another solution that I found, I've updated this solution to include a log file.
This is similar to Publish a Web Application from the Command Line, but just cleaned up and added log file. also check out original source http://www.digitallycreated.net/Blog/59/locally-publishing-a-vs2010-asp.net-web-application-using-msbuild
Create an MSBuild_publish_site.bat (name it whatever) in the root of your web application project
set msBuildDir=%WINDIR%\Microsoft.NET\Framework\v4.0.30319
set destPath=C:\Publish\MyWebBasedApp\
:: clear existing publish folder
RD /S /Q "%destPath%"
call %msBuildDir%\msbuild.exe MyWebBasedApp.csproj "/p:Configuration=Debug;PublishDestination=%destPath%;AutoParameterizationWebConfigConnectionStrings=False" /t:PublishToFileSystem /l:FileLogger,Microsoft.Build.Engine;logfile=Manual_MSBuild_Publish_LOG.log
set msBuildDir=
set destPath=
Update your Web Application project file MyWebBasedApp.csproj by adding the following xml under the <Import Project= tag
<Target Name="PublishToFileSystem" DependsOnTargets="PipelinePreDeployCopyAllFilesToOneFolder">
<Error Condition="'$(PublishDestination)'==''" Text="The PublishDestination property must be set to the intended publishing destination." />
<MakeDir Condition="!Exists($(PublishDestination))" Directories="$(PublishDestination)" />
<ItemGroup>
<PublishFiles Include="$(_PackageTempDir)\**\*.*" />
</ItemGroup>
<Copy SourceFiles="#(PublishFiles)" DestinationFiles="#(PublishFiles->'$(PublishDestination)\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="True" />
</Target>
this works better for me than other solutions.
Check out the following for more info:
1) http://www.digitallycreated.net/Blog/59/locally-publishing-a-vs2010-asp.net-web-application-using-msbuild
2) Publish a Web Application from the Command Line
3) Build Visual Studio project through the command line
My solution for CCNET with the Web.config transformation:
<tasks>
<msbuild>
<executable>C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe</executable>
<workingDirectory>E:\VersionesCC\Trunk_4\SBatz\Gertakariak_Orokorrak\GertakariakMS\Web</workingDirectory>
<projectFile>GertakariakMSWeb2.vbproj</projectFile>
<targets>Build</targets>
<timeout>600</timeout>
<logger>C:\Program Files\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MSBuild.dll</logger>
<buildArgs>
/noconsolelogger /p:Configuration=Release /v:diag
/p:DeployOnBuild=true
/p:AutoParameterizationWebConfigConnectionStrings=false
/p:DeployTarget=Package
/p:_PackageTempDir=E:\Aplicaciones\GertakariakMS2\Web
</buildArgs>
</msbuild>
</tasks>
On VS2012 and above, you can refer to existing publish profiles on your project with msbuild 12.0, this would be equivalent to right-click and publish... selecting a publish profile ("MyProfile" on this example):
msbuild C:\myproject\myproject.csproj "/P:DeployOnBuild=True;PublishProfile=MyProfile"
I've got a solution for Visual Studio 2012: https://stackoverflow.com/a/15387814/2164198
However, it works with no Visual Studio installed at all! (see UPDATE).
I didn't checked yet whether one can get all needed stuff from Visual Studio Express 2012 for Web installation.
A complete msbuild file with inspiration from CubanX
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Publish">
<RemoveDir Directories="..\build\Release\Web\"
ContinueOnError="true" />
<MSBuild Projects="TheWebSite.csproj"
Targets="ResolveReferences;_CopyWebApplication"
Properties="Configuration=Release;WebProjectOutputDir=..\build\Release\Web;OutDir=..\build\Release\Web\bin\"
/>
</Target>
<Target
Name="Build"
DependsOnTargets="Publish;">
</Target>
</Project>
This places the published website in the Web..\build\Release folder

TeamCity - problem with Publish on ASP.net site

I am trying to configure TeamCity 5.0 to run "Publish" target on one of my projects.
When I load the solution in VS 2008 and click publish on the project the website is being build nicely - files on server appearing by themselves etc. Yet when I run the sln file via TeamCity Sln2008 runner the TeamCity returns:
[Project "Portal.csproj" (Publish target(s)):] Skipping unpublishable project.
Has anyone had the same problem?
Filip
You could create your own simple build file. For example:
<Project DefaultTargets="Build" ToolsVersion="3.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
<PropertyGroup>
<PackageFolder>C:\Builds\AppServer\Actual</PackageFolder>
</PropertyGroup>
<Target Name="Build" DependsOnTargets="BeforeBuild">
<MSBuild Projects="TeamWork-AppServer.sln"
Targets="Rebuild"
Properties="Configuration=Debug;OutDir=$(PackageFolder)\;"></MSBuild>
</Target>
</Project>
Or you can use VS 2008 Web Deployment Project. Here is a great turtorial.
If it is a WebProject you can use the Microsoft.WebApplication.targets. Unless you have installed the windows SDK on your build agent you will need to copy the targets file into your source control and reference it from your web project by adding:
<Import Project="{path to your tools}\Microsoft.WebApplication.targets" />
You can find the targets file here (depending on your os):
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v9.0\WebApplications
Now you just need to update your msbuild task to reference the right targets:
<MSBuild Projects="{path to your web project file}"
Targets="Build;ResolveReferences;_CopyWebApplication"
Properties="Configuration=Release;Architecture=Any;WebProjectOutputDir={your web root};OutDir={your web root}\bin\" />
Here is how I modified the .csproj file for an ASP.NET MVC project to deploy via TeamCity 5.1.2. In the .csproj file, replace the AfterBuild target with this XML (If there are already commands in your existing AfterBuild, you will have to merge them into these targets):
<PropertyGroup>
<DeployTarget>0</DeployTarget>
<PublishTarget>0</PublishTarget>
<PublishFolder>..\Deployment\YourWebsiteName</PublishFolder>
</PropertyGroup>
<Target Name="PublishProperties">
<CreateProperty Value="$(PublishFolder)">
<Output TaskParameter="Value" PropertyName="WebProjectOutputDir"/>
</CreateProperty>
<CreateProperty Value="$(PublishFolder)\bin\">
<Output TaskParameter="Value" PropertyName="OutDir"/>
</CreateProperty>
</Target>
<Target Name="WebPublish" DependsOnTargets="BeforeBuild;PublishProperties">
<RemoveDir Directories="$(PublishFolder)"
ContinueOnError="true" />
<CallTarget Targets="ResolveReferences;_CopyWebApplication" />
</Target>
<Target Name="Deploy" DependsOnTargets="WebPublish">
<CreateProperty Value="Path\To\Your\Server" Condition="$(DeployFolder) == ''">
<Output TaskParameter="Value" PropertyName="DeployFolder"/>
</CreateProperty>
<RemoveDir Directories="$(DeployFolder)" Condition="$(CleanDeploy) == 1" />
<ItemGroup>
<DeploymentFiles Include="$(PublishFolder)\**\*.*" />
</ItemGroup>
<Copy SourceFiles="#(DeploymentFiles)"
DestinationFolder="$(DeployFolder)\%(RecursiveDir)" />
</Target>
<Target Name="AfterBuild">
<CallTarget Targets="WebPublish" Condition="$(PublishTarget) == 1" />
<CallTarget Targets="Deploy" Condition="$(DeployTarget) == 1" />
</Target>
This script uses the $(PublishTarget) and $(DeployTarget) properties to trigger additional steps after your project is built. The PropertyGroup at the beginning sets the default values to 0, so the extra targets are not run. You can override the default in TeamCity by going to the Properties and Environment Variables page of your build configuration and adding System Properties names "PublishTarget" and "DeployTarget" and setting their value to 1.
The Publish target contains most of the magic. This makes a call to the Visual Studio _CopyWebApplication target to output the website to the PublishFolder. By default the publish folder is "..\Deployment\YourWebsiteName" relative to the project file, but this can also be overridden with a System Property. The Deploy target takes the files output by the Publish target and copies them to the DeployFolder. DeployFolder can be set with a System Property in TeamCity or you can replace the "Path\To\Your\Server" path in the Deploy target.
You could also skip the extra Deploy step by simply setting the PublishFolder to whatever your deployment destination is. This script depends on the "Microsoft.WebApplication.Build.Tasks.Dll" and "Microsoft.WebApplication.targets" files installed by Visual Studio, but you can simply copy the files from your developer workstation to the build server. The default location is "C:\Program Files\MSBuild\Microsoft\VisualStudio\v10.0\WebApplications".
I have this same problem, here's what I've tried:
I have a solution file in Visual Studio 2010, committed to a Mercurial repository.
I have setup an FTP server for the root directory of the site to publish to, and publishing from within Visual Studio 2010 locally works nicely, it connects and uploads everything as expected, and the website works.
Now, I wanted to automate this on every push to the central Mercurial repository, and since I'm using TeamCity, I discovered that the field to specify the Target of the build, usually "Rebuild" can also take "Publish", so I specified "Rebuild;Publish", as per the documentation and help.
I have verified that after publishing in Visual Studio, and committing new files, a file named ProjectName.Publish.xml is accompanying my ProjectName.csproj file, and this file is pulled down into the server directory when TeamCity builds.
Yet, no publishing is done, and when I check the build log, it says:
[19:01:02]: [Project "Test.sln" (Rebuild;Publish target(s)):] Project "Test.UI.Web.csproj" (Publish target(s)):
[19:01:02]: [Project "Test.UI.Web.csproj" (Publish target(s)):] Skipping unpublishable project.
Exactly as the question here says.
Note that this is a development site, publishing just so that we can let more people test changes, so don't get into a discussion of whether this is actually a good idea or not.
Note: I do not care in which way the files are published, I just need the single TeamCity build-step to actually do it, so if anyone got a MSBuild-like solution that just sidesteps TeamCity, then I would be satisfied
Have you tried to execute Visual Studio directly, rather than relying on MSBuild to publish the project directly. MSBuild can't execute certain kinds of projects. I had a similar problem with getting MSI's built from within Team City.
I'm taking a guess at the exact commandline settings to this, since I don't know your exact setup.
<PropertyGroup>
<buildconfiguration>Release</buildconfiguration>
<DevEnv>C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\devenv.com</DevEnv>
</PropertyGroup>
<Exec Command="%22$(DevEnv)%22 /build $(buildconfiguration) $(teamcity_build_checkoutDir)\Test.sln /project Test.UI.Web.csproj"/>
If you're using the Team City solution runner as your build runner, you'll have to switch to MSBuild.
If you want to stay with the Team City runner, you could always try adding a project to your solution that will be the last one built, (or do it on the project that currently gets built last), and do the spawning trick as a post-build command line on the project.
Can TeamCity publish a Web project using the sln2008 build runner
Can TeamCity publish a Web project using the sln2008 build runner?
What type of project are you trying to publish?
http://social.msdn.microsoft.com/forums/en-US/msbuild/thread/7ec0d942-6354-41c3-9c97-7e7d1f461c29
Taken from above link:
What I discovered is that "Shared-addins" are not publishable
and are distinct and different from document and application level
VSTO addins, which are deployable.
When I rebuilt my application as an application level
VSTO addin, the publish option was available.
http://www.automise.com/Default.aspx?tabid=53&aft=9813
Taken from above link:
Assuming you're using Visual Studio 2008, we're unable to execute the web site
publish feature from FinalBuilder as it's partially implemented by the VS IDE.
You'll need to use to the MSBuild action to compile the application and then
use one of the other actions (FTP, File Copy, etc) in FinalBuilder to perform
the deployment. Visual Studio 2010 has fixed this problem by performing the
entire publish using MSBuild, see this post for more info:
http://www.finalbuilder.com/forums....&afv=topic
Two threads that might help
http://devnet.jetbrains.net/thread/280420;jsessionid=5E8948AE810FFFF251996D85E7EB3FE3
Visual Studio. Publish project from command line
For anyone using Web Application Projects in VS2010, I managed to get TeamCity to package the deliverables and then Web Deploy the package after successfully building the solution.
With a little tweaking, this had the same effect as hitting the 'Publish' button in VS.
My solution has a handful of projects, 1 of which is an ASP.NET MVC Web Application project. I build the solution, package the web app project, and msdeploy the package in 3 steps. I haven't figured out a (better|shorter|simpler|more elegant) way to do this.
I don't have VS installed on my TeamCity server, so I needed to grab both C:\Program Files\MSBuild\Microsoft\VisualStudio\v10.0\Web and C:\Program Files\MSBuild\Microsoft\VisualStudio\v10.0\Web Applications and put them both in the same spot on the TeamCity server (the second depends on the first). If you're working w/x64 machines, I'd grab them from both Program Files (x86) and Program Files. You also need to have Web Deploy installed on your machine and (I believe) IIS Management Service (i.e., something listening on https://yourservername:8172/MsDeploy.axd)
There are 3 build steps:
Visusal Studio (sln), Target=Rebuild, Configuration=Debug
MSBuild WebProject.csproj, Targets=Package Commandline=/p:PackageLocation=%teamcity.build.checkoutDir%\Debug.zip /p:Configuration=Debug
Commandline, Executable=%teamcity.build.checkoutDir%\Debug.deploy.cmd, Parameters=
/Y "-setParam:'IIS Web Application Name'='Default Web Site/PreCreatedAppInIis'"
In that last step, 'IIS Web Application Name' is an actual parameter name, don't change it. It's value can either be something like 'Default Web Site' or whatever you named your website in IIS and/or it can be an IIS application path below it. If the application doesn't exist, you may run into errors about the app pool not being configured correctly to host the application. Rather than investigate it, I just created an application in the appropriate app pool. In my case, I'm targeting ASP.NET 4.0 x64 where the default app pool is ASP.NET 2.0 x64.

Checking a file out (TFS) for a pre-build action

I've added a pre-build action for an ASP.NET web control (server control) project, that runs jsmin.exe on a set of Javascript files. These output files are part of the source control tree and are embedded into the assembly.
The problem is when the pre-build runs, jsmin can't write the file as it's readonly. Is it possible to check the file out before hand? Or am I forced to set the file's attributes in the command line.
Any improved solution to the problem is welcome.
Update
One small issue with Mehmet's answer -you need to prepend the VS directory:
"$(DevEnvDir)tf" checkout /lock:none "$(ProjectDir)myfile"
If you're using Team Foundation Server, you can use team foundation command line utility (tf.exe) to check out the file(s) during pre-build and then check them back in during post-build. If you're using something else for source control, you can check if they have a command line tool like tf.exe.
If you do not want to check the files in as part of the build (which you normally wouldn't for this sort of thing) then I would simply set the attributes of the .js files before running jsmin on them. The easiest way of setting the files read-writeable is to use the the Attrib task provided by the MSBuild community extensions. The same community extensions also provide a JSCompress task for easily calling JSMin from MSBuild.
Therefore you'd have something like the following (not tested):
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />
<!-- rest of TFSBuild.proj file -->
<Target Name="AfterGet">
<Message Text="Compressing Javascript files under "$(SolutionRoot)"." />
<CreateItem Include="$(SolutionRoot)\**\*.js">
<Output TaskParameter="Include" ItemName="JsFiles"/>
</CreateItem>
<Attrib Files="#(JsFiles)" ReadOnly="false"/>
<JSCompress Files="#(JsFiles)" />
</Target>
Note that by modifying the files after getting them may well cause issues if you tried to move to an incremental build.

Resources