26 May 2009

After my last post on building WSP in TFS, I was at a stage where I thought the WSP file was ready to go. It's recognised by WinRAR, opening it up in there shows the expected dll's.

But there was something missing...

feature.xml

Attempting to deploy the WSP threw:
Failed to find the XML file at location '12\Template\Features\IL.SharePoint.Workflows\feature.xml'

This TechNet page on InstallFeature clears up the exact cause being a missing feature.xml. It also cleared up that the 'root' of the WSP is equivalent to 12\Template\Features\ a location in the "12 hive".

Opening up the WSP, sure enough there was no sign of feature.xml, so it was time to head back into WSPbuilder.exe -help where I found...

-12path

The default for the 12path is the current directory, here again, since we're not running from the project directory, the current directory isn't much good, so I needed to set the 12 path.

Setting the 12path to the location of the feature.xml got it included in the WSP, but the manifest.xml included it in the RootFiles element. Based on our manually built WSP, we saw we needed it to be in the FeatureManifests element.

After some searching I looked again at the before build image on the WSPBuilder CodePlex site. Turns out this is rather useful once you know what you're looking at. There you'll see the path WSPDemo/12/Template/FEATURES/WSPDemo/; after seeing that, it dawned on me that I had actually read something about "putting the contents of your 12 hive into the project folder" - so that's what they meant.

So finally the files were included in the WSP in the right location:

-DeploymentTarget GAC

Because of the way our solution is set up we need to target the GAC, we were getting:
<Assembly Location="IL.SharePoint.Workflows.dll" DeploymentTarget="WebApplication" />
in the manifest.xml. Changing the DeploymentTarget from the default of Auto to GACyielded the required:
<Assembly Location="IL.SharePoint.Workflows.dll" DeploymentTarget="GlobalAssemblyCache" />

-BuildCAS False

The default for this is True, with it on, the manifest file was spammed full of CAS information and trying to deploy gave the error:

The solution "IL.SharePoint.Workflows.wsp" needs to add Code Access Security policies. If you fully trust this solution, use the -allowCasPolicies parameter to deploy.
True, using -allowCasPolicies did remove the error, but adding -BuildCAS False cleaned up the manifest file and removed the need for this switch to stsadm.

Revised WSPBuilder command line

All this meant the following amended Exec command in the tfsbuild.proj.

    <Exec Command='"C:\Program Files\WSPTools\WSPBuilderExtensions\WSPBuilder"

          -DeploymentTarget GAC

          -BuildCAS false

          -SolutionPath "$(OutDir)"

          -BinPath "$(OutDir)"

          -OutputPath "$(WspDir)"

          -12Path "$(OutDir)12"

          -WSPName IL.SharePoint.Workflows.wsp'

          />

Posted on Tuesday, May 26, 2009 by David Campey

No comments

14 May 2009

We needed to build a Sharepoint WSP file in TFS as part of our continuous integration process. Already using WSPBuilder interactively we just needed to get it into the team build and copied to the staging location.

WSPBuilder

Brian Farnhill discusses the process of building a WSP in TFS by first including it in the project file (summary by Alex Degaston). This pointed me in the right direction, but I really just wanted to build the WSP in the team build after check-in.

We just copied the basics from Brian's post, and hoped it would work, and amazingly, we had a WSP file. Frustratingly, the WSPBuilder will happily create a WSP file even if it finds nothing to put in it.

After some experimenting on the command line, it turns out you need to specify both SolutionPath and BinPath to get WSPBuilder to build successfully, using the team build property OutDir worked for this. Including the feature.xml and workflow.xml as content in the root of the project ensures they're in the output folder.

The default name for the WSP is the folder name, so to override this, use WSPName.

File drop

The easiest way to get the files out was to override BeforeDropBuild and put them in the OutDir. I'm using xcopy for this as it's easier to test on the command line (also, using the copy task would require (I think) further nesting the copy operation because of the order of item expansion). They're then ready for the team build to perform the drop to the staging location.

Finally

All this boils down to this two liner added to the TFSBuild.proj:

  <Target Name ="BeforeDropBuild" >

    <PropertyGroup>

      <WspDir>$(SolutionRoot)\Code\IL.SharePoint.Workflows\DeploymentFiles</WspDir>

    </PropertyGroup>

    <Exec Command='"C:\Program Files\WSPTools\WSPBuilderExtensions\WSPBuilder"

          -SolutionPath "$(OutDir)"

          -BinPath "$(OutDir)"

          -OutputPath "$(WspDir)"

          -WSPName IL.SharePoint.Workflows.wsp'

          />

    <Exec Command='xcopy /E /Y /I

          "$(WspDir)"

          "$(OutDir)DeploymentFiles"'

          />

  </Target>

Posted on Thursday, May 14, 2009 by David Campey

No comments

12 May 2009

Trawling through Microsoft.TeamFoundation.Build I found the flag for IncrementalGet. Not getting full sources every time has cut 40 seconds out of every build. This is particularly useful when debugging a build script.

Buck Hodges discusses IncrementalGet and IncrementalBuild and links to Martin Woodward's 30 Useful Team Build Properties. Not sure I'm ready for IncrementalBuild yet, I like having shiny new dll's.

This is what I added to my root level PropertyGroup just before DropLocation:

    <!-- INCREMENTAL GET

      Setting this flag will set:

      CleanCompilationOutputOnly: true

      SkipInitializeWorkspace: true

      ForceGet: false

      (Microsoft.TeamFoundation.Build Line:379)

    -->

    <IncrementalGet>true</IncrementalGet>

Posted on Tuesday, May 12, 2009 by David Campey

No comments