Automated Nightly SharePoint Builds By Person With Incremental Get

One build scheme that I recently had a client that was heavily reliant on TFS was the desire to do automated night builds with a full get, as well as person based builds in the queue only did incremental gets. The problem that they were running into was there were only incremental gets occurring, even when the build was requested by the Build System Account.

In order to get around this, the solution was to slightly adjust their builds by writing the $(RequestedBy) out with the Message task. Then override the BeforeGet target and set the IncrementalGet property with the CreateProperty task.

Easy as pie!

Share

SharePoint WebPart Versioning

WebPart versioning is a discussion that I have with clients, as well as internally, consistently. Largely this is because it can hit sensitive organizational points (if they have a reasonable software development initiative) and is terribly prone to developer opinion. It can rapidly move from a pragmatic to esoteric discussion.

For these reasons, it is challenging to structure a best practice regarding WebPart versioning, since there really is no best practice. However, after presenting some options I think it is reasonable to assume that an organizational best practice can be cultivated and everyone can be happy.

To try to get those gears turning, I am going to fly through at a 10,000 foot view of various problems typically encountered when implementing a WebPart versioning strategy, some approaches, and a base class that I use that leverages one of the discussed version approaches using a display vehicle I like the most.

Before I continue, let me state that the remainder of this post is going to assume strong named/signed assemblies, as well, these assemblies are being stored in the GAC.

Problems with Versioning

Arguably, the most difficult segment to tackle when dealing with WebPart versioning is that the AssemblyVersion attribute tends to be of little use because WebParts can be considered to use static versioning. AssemblyVersion within orthodox managed development tends to be heavily leveraged because it defines an integral number regarding the assembly’s identity. So, why is the AssemblyVersion such an ineffective mechanism to rely on when dealing with SharePoint WebPart development?
There are three main reasons:

Referencing the AssemblyVersion attribute, as managed assemblies in the GAC do, will break if this value changes.

The SharePoint WebPart Description File (.webpart or .dwp) references the AssemblyVersion attribute within the type element in its XML structure. This element consists of a string with type and assembly information about the corresponding webPart element. As a result, any description files already instantiated on a page won’t bind right due to an incorrect assembly version number.

Without modifying the safe controls entries for the SharePoint site, there will be an assembly mismatch when altering the AssemblyVersion number, resulting in a safe control error when attempting to render the WebPart (if already on a page, otherwise it won’t be allowed on the WebPartPage). This can be solved with solution redeployment or manual web.config modifications; however you are following still subject to the same problem as described above so while fixable, isn’t a rational solution.

There are some more issues, most I consider negligible so I won’t go over them; however those are the largest ones.

Versioning Storage

In order to resolve not having a dependency on the AssemblyVersion, a margin of people rely on the AssemblyFileVersion attribute since this can arbitrarily change with little effect on the WebPart. Use of this also provides the same experience as using the AssemblyFileVersion since this value is mutable from VS.NET with nearly the same invocation. As well, for people that are using Reflection in order to hydrate objects with the relevant assembly information, the mechanics are consistent once you have an Assembly object.

Otherwise, static string representation is simple and popular. This involves setting the values of the version and build name within the assembly, a satellite assembly, or from some other arbitrary source. It could be a wide range of objects, even from a tabulated text file, it doesn’t really matter. All that matters is that the version information is read from a source, and that source is not the calling assembly.

Choosing a Display Vehicle

The display mechanisms for versioning vary depending on the organization. I have seen in the majority of projects these four major types:

Toggle the corresponding SharePoint Feature description element prior to the SharePoint solution packaging.

Just format and dump it out to directly out to standard output as part of the control.

Add a new WebPartVerb object to the current instance WebPartVerbCollection with the version information.

Add a new EditorPart to the current instance EditorPartCollection with the version information

Making It Work

As an example, I am going to use the last option, and place my versioning information in an EditorPart object. In order to consistently enforce this across multiple WebPart type projects, a new base WebPart class for subclass use will be defined which contains all the relevant code to handle the versioning. In order to pass unique values for the program name and the version number, the derived class constructor will be used. The approach is similar to using the WebPartVerb approach, and could easily be ported over to that construct if EditorPart  objects don’t really blow your back.

To do this, three different classes are used. VersionInfo contains a static method that renders to standard output the required strings using strongly typed formatting objects. EditorVersionPart inherits from the EditorPart class, and contains two backing fields that are toggled in the constructor. EditorVersionPart calls the static VersionInfo.CreateVersion method to build out the visual representation of the version information. The WebPartBase class inherits from the WebPart, and IWebEditable interface. Regarding the latter of these, its type members are implemented, which call the custom EditorVersionPart class.

As a result of using this class, you will be presented with the following when using it as your base class, demonstrated in a trivial WebPart.

In order to provide the required strings, in the WebPart constructor the desired values are being provided.

As a result, the WebPart class structure will take on the following form:

[csharp]
namespace buenz.SharePoint.WebParts
{
public class VersionDemo : WebPartBase
{
public VersionDemo()
{
_name = “My WebPart”;
_version = “1.0.0.0 (Debug / Checked)”;
}
}
}
[/csharp]

And the related classes to achieve this effect are:

[csharp]
using System;
using System.Collections.Generic;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using midwave.SharePoint.WebParts;

namespace buenz.SharePoint.WebParts
{
public class VersionInfo
{
public static void CreateVersionSegement(HtmlTextWriter writer, string version, string name)
{
var tbl = new Table {HorizontalAlign = HorizontalAlign.Center};
var row = new TableRow {HorizontalAlign = HorizontalAlign.Center};
var versionRow = new TableRow {HorizontalAlign = HorizontalAlign.Center};
var cell = new TableCell {HorizontalAlign = HorizontalAlign.Center, Text = string.Format(“{0}”, name)};
var versionCell = new TableCell {HorizontalAlign = HorizontalAlign.Center, Text = string.Format(“{0}”, version)};
row.Cells.Add(cell);
versionRow.Cells.Add(versionCell);
tbl.Rows.Add(row);
tbl.Rows.Add(versionRow);
tbl.RenderControl(writer);
}
}
}

public class EditorVersionPart : EditorPart
{
public string _name;
public string _version;

public EditorVersionPart(string webPartID, string name, string version)
{
Title = “WebPart Versioning”;
ID = string.Format(“MyEditorPart{0}”, webPartID);
_name = name;
_version = version;
}

protected override void RenderContents(HtmlTextWriter writer)
{
base.RenderContents(writer);
VersionInfo.CreateVersionSegement(writer, _version, _name);
}

public override bool ApplyChanges()
{
EnsureChildControls();
return true;
}

public override void SyncChanges()
{
EnsureChildControls();
}
}

public class WebPartBase : WebPart, IWebEditable
{
public string _name;
public string _version;

EditorPartCollection IWebEditable.CreateEditorParts()
{
var editors = new List {new EditorVersionPart(ID, _name, _version)};
return new EditorPartCollection(editors);
}

object IWebEditable.WebBrowsableObject
{
get { return this; }
}
}

}

[/csharp]

Happy Versioning! :)

Share

Differentiating Between the Cost and Value of SharePoint

In class today, we had a heated debate regarding trustworthy, commercial collaborative software. Not surprisingly, I took the side of SharePoint so joined the group preparing the argument for the Microsoft stack (it was small group session breakout). Interestingly, the argument ended in a stalemate after both presented cases, both sides agreeing that each has their inherent benefits (its god damn hard to come up with an ample argument against Open Source benefits), and innate faults. However, from that preliminary argument, a new dialogue was produced. Regardless of the stack choice that either group was defending, it is typical that management level sponsorship for collaborative environment efforts often has difficulty pegging down the value of standing up a collaborative software instance.

The celebrated dramatist Oscar Wilde once said:

A cynic is a man who knows the price of everything but the value of nothing.

This quote to me means numerous things (since it is so open to elucidation), however none more exceptional than the simplest interpretation. A person at times can repeatedly put an empirical cost on an arbitrary object since this is, well, pragmatic. However, to get something that is not as tangible such as Realized Business Value (RBV) or Return On Investment (ROI) for a collaborative effort is remarkably curious. Although the cost is certainly going to play a parameter when generating your Realized Business Value Docket (RPVD), it certainly is only that, a piece of input while in the presence of other inputs that hold more weight (this is one of the strengths of RBV since it provides some basic levels of cost abstraction, and those living in the small-to-medium size vertical the purchase of SharePoint can be quite expensive).

I want to stress that in my opinion, measuring things like monetized ROI on collaborative software efforts leveraging legacy business value approaches is a façade, a mirage, an illusion (this might not apply to some of its subsets). Just don’t even try it, it’s self-defeating and will only suffice in providing a depressing, dismal night where you are fudging numbers more than harvesting from the actual project.

This isn’t to say that you can’t acquire value with output metrics with collaborative software efforts, but it is problematic to present your findings to management since they can prove to be abstract and often times contain a buttload of inference. Commonly, at a most basic level, a manager is going to expect that he can gain an object for a cost from someone and somewhere, and from these parameters as well as insight into the owning organization, an ROI can be determined and implemented. In the end, we can say that managers tend to be good at looking at a particular project with a pair of monetization spectacles, compensating for human factors like apathy to technology. Taking this monetizing approach when attempting to appreciate the value of SharePoint, as well as all collaborative software, is not practical however.

Why? The outputs are different. Plain and simple. Whereas with traditional software development efforts we can do the type of surveying of project results as described previously, this is unquestionably not the case with SharePoint. Collaborative software has outputs such as:

Augmented Information Worker Knowledge
Improved Employee Productivity
Enhanced Customer Service

And while I can name these out just fine, and in some fashion there may be some methods to garnish metrics from them (notably the Enhanced Customer Service entry), how does one place a value on something like enhanced information worker knowledge. While we can certainly see whether there are variations between productivity, this reporting is in essence very circumstantial because we are pretty much preparing a collection of facts rather than a conclusive series. There could be too many factors involved that could cause discrepancies for any of these during that process, as well as for the aggregate output.

So, stuff like this is somewhat conjectural at the moment. I think that the best way to measure something like this would be with revolving, time adjusted surveillance of collaborative software utilization growth and taking into account parallel visualization of the stored and delivered data. However, I don’t think that is enough, because that is only a very small part of the measurement. Rather, it would have to be inclusive to include the more human factors, such as how often a person is involved in face-to-face interactions, movement patterns that occur in the workspace, etc. This type of research would be even further constrained as it would have to compensate for dependencies on legacy collaborative tools, such as email. I am not going to go into the approach I would use with this, I will save that for another post.

I guess what to take away from this, particularly if you are a manager, is this is a new concept and a new type of recognition. And while the benefits might not be immediately available to conventional brick-and-mortar industries, they are there. There just haven’t been any mature, intelligent tools built that inclusively deliver those types of reports.

Yet…… (and the gears start turning). Stay tuned!
:)

Share