Reputation: 14457
I'm trying to switch our build from CruiseControl.NET running a custom .msbuild file to Team Build 2010. The application being compiled is a VS2008 solution with numerous projects, two of which are web projects.
Using DefaultTemplate.xaml, it appears that the two web projects are deployed to Binaries\_PublishedWebsites\(ProjectName)
. That default location is fine. However, the contents of the output directories appear to be updateable, as though aspnet_compiler.exe
was called with -u
, or as though an MSBuild <AspNetCompiler>
task was used with Updateable="true"
. So, two questions:
_PublishedWebsites
directory?How can I also set the IIS VirtualPath as if I was doing the following in an MSBuild task:
<AspNetCompiler Clean="true" Force="true" VirtualPath="/My-IIS-Virtual-Path" />
I have found in earlier troubleshooting that the only way I can get IIS 6 to serve a web service compiled with aspnet_compiler.exe
in non-updateable mode is to specify the virtual path in the command, which is why I am asking about #2.
Edit:
Upon seeing the one answer thus far, I realized I should have been much clearer about what the issue is. I realize that, if I can do something in MSBuild, I can just call MSBuild from the build template. However, I am wondering a little more about how change what happens to copy the output to the _PublishedWebsites
directory. "Find the task that copies the website and change it" would work well, except that I don't see what is actually copying the output into _PublishedWebsites
. What I'm really wanting to do is to modify the step in the template that accomplishes this.
The build log references a compile target called _CopyWebApplication
that appears to do the work of copying the files needed for a web application. However, I am unsure how to modify this compile target, as I do not see it anywhere in the build template nor in any file in the solution. Further, whatever runs _CopyWebApplication
appears to be running it only for web application projects, not the many other projects in the solution. This is a good thing, except that I do not know where the logic exists that determines whether to use _CopyWebApplication
.
Maybe there is some default MSBuild file that I am missing? Some build parameter that I could be using? How do I alter the aforementioned build step?
Upvotes: 4
Views: 3383
Reputation: 14457
KMoraz pointed me in the right direction, and I had to do a few more things to get this working. I really did not want to edit the built-in .targets
files, since that would create some maintenance problems down the line for any other developer who did not know what I did. I ended up editing the .csproj
files for the two web applications to this, starting with the default <Import>
element near the end of the file and ending before the default <ProjectExtensions>
element:
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- Since this Import serves no real purpose in VS2008 under Team Build, I'm commenting it out to remove
a _CopyWebApplication step that we don't want.
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" />
-->
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<!-- Now, for Team Build, do the AspNetCompile steps ourselves. -->
<PropertyGroup>
<WebProjectOutputDir Condition="'$(OutDir)' != '$(OutputPath)'">$(OutDir)_CompiledWebsites\$(MSBuildProjectName)</WebProjectOutputDir>
</PropertyGroup>
<PropertyGroup>
<BuildDependsOn>
$(BuildDependsOn);
DoAspNetCompile
</BuildDependsOn>
</PropertyGroup>
<Target Name="DoAspNetCompile" Condition="'$(CompileWebsites)' == 'True' And '$(OutDir)' != '$(OutputPath)'">
<Message Text="Performing AspNetCompile step for $(MSBuildProjectName)" />
<Message Text="Output will have IIS virtual directory '$(IISVirtualPath)'" />
<Message Text="ProjectDir is $(ProjectDir)" />
<Message Text="IsDebug is $(IsDebug)" />
<RemoveDir Directories="$(WebProjectOutputDir)" ContinueOnError="true" />
<MakeDir Directories="$(WebProjectOutputDir)" />
<!-- We need the /bin directory, populated with some DLLs and PDBs -->
<CreateItem Include="$(OutDir)*.dll;$(OutDir)*.pdb">
<Output TaskParameter="Include" ItemName="BinariesToCopy" />
</CreateItem>
<Copy DestinationFolder="$(ProjectDir)\bin" SourceFiles="@(BinariesToCopy)" />
<AspNetCompiler Clean="True" Force="True" Debug="$(IsDebug)" Updateable="False" VirtualPath="$(IISVirtualPath)" PhysicalPath="$(ProjectDir)" TargetPath="$(WebProjectOutputDir)" />
</Target>
Some explanations:
.csproj
file, as you can see, that C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets
is in use by default. I did not realize previously that was how MSBuild knew to use that .targets
file. Since the only way not to use the target file's _CopyWebApplication
target under VS2008 is not to use the file, and since the VS2010 version really did not help me either, I just commented out the import._CompiledWebsites
instead of _PublishedWebsites
.<BuildDependsOn>
element so that any other project files down the road that modify the extension points do not disable my target.CompileWebsites
is set to true (using something like the /p:CompileWebsites=true
parameter passed to MSBuild, though within Team Build, there are also other ways to accomplish this if desired). That way, the default local build is unaffected.<Message>
elements are for debugging. I have set $(IsDebug)
to True or False in the configurations near the top of the file. We have many configurations besides vanilla "Debug" and "Release", so this flag was necessary so I could tell AspNetCompiler
whether to include debugging symbols. $(IISVirtualPath)
is also set in the configurations near the top of the file. It is necessary so that IIS 6 will serve a web service compiled in this manner.AspNetCompiler
cannot find the precompiled binaries where Team Build puts them by default, so I copy them to the bin\
directory of the project, where AspNetCompiler
expects to find them./p:CompileWebsites=True
parameter. To accomplish this, right-click the build definition in the Team Explorer window (under Builds under your team project), click "Process", expand the "3. Advanced" entry, and enter /p:CompileWebsites=True
for the line labeled "MSBuild Arguments".If I had more than two projects that needed this build configuration, I would probably create a file with the DoAspNetCompile
target and import that file.
Upvotes: 4
Reputation: 14164
All logic of the _CopyWebApplication
target is defined in:
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets
The target itself is rather simple but it carries a bunch of pre-conditions:
<Target Name="_CopyWebApplication"
Condition="!$(Disable_CopyWebApplication) And '$(OutDir)' != '$(OutputPath)'"
DependsOnTargets="$(_CopyWebApplicationDependsOn)">
<CallTarget Condition="'$(OnAfter_CopyWebApplication)' != ''" Targets="$(OnAfter_CopyWebApplication)" RunEachTargetSeparately="true" />
</Target>
You can control the process once getting to the desired set of flags. The following are the defaults:
<WebProjectOutputDirInsideProjectDefault>True</WebProjectOutputDirInsideProjectDefault>
<WebProjectOutputDirInsideProjectDefault Condition="('$(OutDir)' != '$(OutputPath)') Or ('$(IsDesktopBuild)' == 'False')" >False</WebProjectOutputDirInsideProjectDefault>
<DisableLinkInCopyWebApplicaton Condition="'$(DisableLinkInCopyWebApplicaton)'==''">False</DisableLinkInCopyWebApplicaton>
<Disable_CopyWebApplication Condition="'$(Disable_CopyWebApplication)' == ''">False</Disable_CopyWebApplication>
<UseWPP_CopyWebApplication Condition="'$(UseWPP_CopyWebApplication)' == ''">False</UseWPP_CopyWebApplication>
<CleanWebProjectOutputDir>True</CleanWebProjectOutputDir>
<CleanWebProjectOutputDir Condition="$(WebProjectOutputDirInsideProject)" >False</CleanWebProjectOutputDir>
Upvotes: 4
Reputation: 3596
The DefaultTemplate.xaml in TFS 2010 Build still uses MSBuild to build your projects, so if the two things that you list can be done with MSBuild.exe, they can be done with the 2010 build process. All you need to do is to add the MSBuild arguments you want to the Process Parameters of your build definition. More details about updating your build definition can be found on MSDN.
Upvotes: 2