I’m not sure why I put myself through this pain (generating documentation of the assemblies I check in) because it just highlights how much Gareth R. is right that Documentation isn’t the bee’s knees when one doesn’t put anything explanatory in the comments…. (he was grumpily looking at some of my code)…but what the hey…this is a way to do it.
Btw, turned out to be a heck of a lot easier than the last time I set this up, on CruiseControl.
- Install SandCastle
- On the Server
- On the Dev Desktop
- Install SandCastle Help File Builder
- Use The GUI / Helper to create a *.shfbproj, filling in the details (copyright, etc.)
- I prefer convention over configuration, so it doesn’t matter what strategy you use – as long as you have a consistent one.
I put the the above *.shfbproj file in the same dir, within each *.csproj in the *.sln. - MySol\MySol.sln
- MySol\Proj1\Proj1.csproj
- MySol\Proj1\_Documentation\Documentation.shfbproj
- MySol\Proj1\Proj2.csproj
- MyPos\Proj2\_Documentation\Documentation.shfbproj
- In TeamCity, I created a PowerShell script – all on a single line – that does:
get-childitem "." -recurse | Where {$_.extension -eq ".shfbproj"} |
foreach-object { C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe $_.Fullname}
WHat I’m doing here is recursing through all directories below the checkout dir, looking for SandCastle projects, which I then push through Sandcastle.
The output is defined in the *.shfbproj…which, by the way, I took a hint from how NuGetPowerTools was doing it, and manually edited the msbuid fild to put some params. This helps me not have to chase down typos and forgotten variables later…
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<!-- The configuration and platform will be used to determine which
assemblies to include from solution and project documentation
sources -->
<ProjectName Condition="$(ProjectName) == '' Or $(ProjectName) == '*Undefined*'">XAct.Core</ProjectName>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\..\</SolutionDir>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{46253163-f374-4476-926a-55b3bd241d05}</ProjectGuid>
<SHFBSchemaVersion>1.9.3.0</SHFBSchemaVersion>
<!-- AssemblyName, Name, and RootNamespace are not used by SHFB but Visual
Studio adds them anyway -->
<AssemblyName>Documentation</AssemblyName>
<RootNamespace>Documentation</RootNamespace>
<Name>Documentation</Name>
<!-- SHFB properties -->
<OutputPath>$(SolutionDir)\_Deliverables\Documentation\$(ProjectName)\</OutputPath>
<HtmlHelpName>$(ProjectName)</HtmlHelpName>
<Language>en-US</Language>
<HelpFileFormat>Website</HelpFileFormat>
<DocumentationSources>
<DocumentationSource sourceFile="..\$(ProjectName).csproj" xmlns="" />
</DocumentationSources>
<CopyrightText>Copyright XAct Software Solutions, Inc.</CopyrightText>
<FeedbackEMailAddress>xactlib%40xact-solutions.com</FeedbackEMailAddress>
<Preliminary>True</Preliminary>
<HelpTitle>$(ProjectName) Documentation</HelpTitle>
<CopyrightHref>legal.xact-solutions.com\XActLib\</CopyrightHref>
<WebsiteSdkLinkType>None</WebsiteSdkLinkType>
<VendorName>XAct Software Solutions, Inc.</VendorName>
<WorkingPath/>
<BuildLogFile />
<HtmlHelp1xCompilerPath />
<HtmlHelp2xCompilerPath />
<SandcastlePath />
</PropertyGroup>
<!-- There are no properties for these groups. AnyCPU needs to appear in
order for Visual Studio to perform the build. The others are optional
common platform types that may appear. -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|Win32' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|Win32' ">
</PropertyGroup>
<!-- Import the SHFB build targets -->
<Import Project="$(SHFBROOT)\SandcastleHelpFileBuilder.targets" />
</Project>
One last thing. Not sure why, but the SHFBROOT variable is installed by SandCastle Help File Builder – but it doesn’t take effect till one restarts the server. Not sure why exactly.
Other points of note.
Not that I’ve needed to yet, but as the *.shfbproj file is just an msbuild file, one can update the PowerShell script to invoke MSBuild using the Parameters property.
Another point is that right after that step, I have another build step that is a simple XCOPY to move the documentation to the website on the same server (would be more complex to move it to another server).
xcopy "_deliverables\documentation\*.*" "X:\SITES\DOCS.XACT-SOLUTIONS.COM\Public\" /E /C /Q /H /R /Y
TeamCity + a *.sln that contains 75 assemblies + a lot of Nuget Package definitions + NuGetPowerTools…. 5th try (about 10 minutes of fiddling)….worked!
I’m impressed!