Posted by Will on Wednesday, June 25, 2008 at 1:06 PM

In the previous episode I intended to cover the configuration of TeamCity, but took a quick detour to talk about MSBuild and MSBuild scripts.  Now that we've got a script to use we can configure TeamCity.  The following will be the minimal steps to get up an running.

  1. To start off, log into your TeamCity installation and click on the Administration button (top right area of screen) to go to the Projects and Build Configurations screen.  This screen will give you an overview of all the projects that you have configured to run on this installation. 
  2. Click on the Create Project link on the page.  Name your project and give it a description then click the Create button.
  3. The next screen will provide you will the options for creating a build configuration and a VCS root.  Here are the values I used under the heading of General Settings:
    • Name: Something that makes sense in your context (i.e., Standard MSBuild).
    • Build number format: I'm currently using 2.0.{0}.{build.vcs.number.1}  The initial 2.0 is static, but {0} is a placeholder for the build counter value.  The {build.vcs.number.1} placeholder is, as the note below the text box says "a reference to VCS changeset number.  So for example 2.0.71.144 means the 71st build using revision 144 of 2.0.  There are different strategies for version number make up.  The important thing is to pick something that works for you and stick with it.
    • Build counter: This allows you to set the build number to a higher seed if for instance you're migrating from another configuration where you've already reached build number.  Conversely, you can also decrement the value if you want to zero the build counter.
    • Click on VCS settings button to continue with the setup.
  4. Version Control Settings are next. 
    • Click on Create and attach a new VCS root.
    • Enter a meaningful name and choose the appropriate type of VCS, in my case Subversion.
    • Fill in the blanks for the URL, and if necessary, user name and password.  There is an option to test the connection at the bottom of the page. 
    • Save your changes to return to the previous page.
    • Back on the Version Control Settings I chose Automatically on server for the VCS checkout mode and left the rest of the settings unchanged.  Click the Choose Build Runner button to advance.
  5. From the Build runner options I chose MSBuild.  The next parameter, Build file path, took me a couple of tries to get right the first I set this up.  The note under the text box says "Specified path should be relative to the checkout directory" but keep in mind that your URL choice in the VCS root options will influence the relative path.  If you have a traditional directory structure of branches, tags, and trunk at your VCS root and specify the root of your source tree then your Build file path may look something like trunk\MyBuildScript.xml.  Two MSBuild versions should be available, the one from the 2.0 and the 3.5 version of the .NET Framework.  I would suggest 3.5 even if you're building a Visual Studio 2005 project.  Click Save.

At this point all of the necessary steps have been completed.  However, TeamCity offers more options that can be configured around your project.  The options are listed on the right side of the screen under Build Configuration Steps heading when you're editing a project.  All of these options are also available from the Edit Configuration Settings link on the project tool bar.  One of the options in particular is worth considering - Build Triggering.  TeamCity offers many options for triggering a build.  The one I found most useful is VCS Triggers.  TeamCity can check for any changes to your source control repository on the interval you choose and run a new build with the changes. 

In order to make use of your project you need to have an authorized build agent available.  Click on the Agents tab in the top left area of the screen.  Under the Agents heading you will see four tabs.  One of them (probably the Unauthorized agents tab) should have a number greater than zero in parenthesis.  Click on that tab.  If it is the Unauthorized agents tab click on the Authorize agent link then move over to the Connected Agents tab and click the Enable agent link if necessary.  Your agent is now available for use.

With your project completed you will find it listed under the Projects tab (top left area of screen).  Choose your project from the drop down menu embedded in the Project tab.  Under the Current status section of the Overview tab if you have a No suitable agents link return to the previous paragraph and check your settings.  From this screen you can trigger a build by clicking on the Run button in the toolbar.  After a second or two the page will refresh and show you the status of the build as it progresses.  The build result will be shown in the Recent history section of the page. 

A word about troubleshooting a failed build: If the build fails you can use the drop down menu in the history list beside the result in the Results column to view the build messages to guide your troubleshooting.  A couple of things that have tripped me up are forgetting to add a newly referenced dll to source control.  Along the same lines, referencing a new dll and not updating the MSBuild script accordingly caused a failed build.  If you have no idea where to begin troubleshooting start by running the script locally from a Visual Studio command prompt.  See the end of Episode 4 for more information.

If you're new to TeamCity I would suggest spending the time to explore the interface and become familiar with the many available options.  As I said at the start of this post, I've only covered the minimal step to get you up and running from a cold start. 

Comments [0]     Categories: Continuous Integration | MSBuild | TeamCity              
Posted by Will on Monday, June 23, 2008 at 2:24 PM

We tell our kids that "hate" is a strong word and to be careful about the words they choose because they reflect the content of their hearts.  That said - I hate making subreports in Visual Studio.  I do it just infrequently enough to forget all the little things you have to do to get them working.  Consequently I end up looking at the world's most useless error message: "Error: Subreport could not be shown".  Never again my friend; this time I'm going to write it down.

In my experience a lot has to go right and pretty much nothing wrong when setting up a subreport for it to work.  I adhere to the following voodoo rituals guidelines:

  • If you can avoid subreports altogether, then do.
  • Remember to configure the parameters for the subreport itself.  The configuration dialog is accessed by right-clicking on the design surface outside of the report boundaries (the gray area) and choosing "Report Parameters" from the context menu.
  • The first time you drag a column from a data source table onto the parent report the IDE makes a reference to that data source in its underlying XML.  Be sure to do this for at least one column of each table that will serve as sources for parameters in a given subreport before configuring the subreport.  Doing this will ensure that the source columns will be available in the subreport configuration dialog of the parent report. 
  • When you specify the report to show in the parent report's subreport control, remember to configure the parameters on the "Parameters" tab of the configuration dialog.  The dialog is accessed by right-clicking the control.  All of the subreport parameters (Parameter Name) must be specified along with their source (Parameter Value).  Watch for spelling and case errors.
  • If you have to modify a table adapter in a typed dataset used by a subreport and that modification adds a column to the table adapter, then it is better to delete the table adapter from the typed dataset and recreate it with the same name with the necessary changes.  I just recently tried modifying an existing table adapter in this way and broke a report that had been working.  Yea, I know.  It's crazy.
  • Sadly, It is often easier and faster to delete and recreate a subreport (and if necessary its parent report) than to troubleshoot one that isn't working.
Comments [0]     Categories: Reporting Services              
Posted by Will on Tuesday, June 17, 2008 at 8:16 PM

cicada2cicadaThe 17 year cicadas are out.  They were so loud this weekend that I could hear them over the lawnmower while wearing earplugs.  I took these shots in the back yard.  It was on the cherry tree.  We actually still have cherries this year because the birds are eating these guys instead of the fruit. 

I'm sure the cherries will be gone shortly after the cicadas.

 

 


Comments [0]     Categories: Off Topic              
Posted by Will on Friday, June 13, 2008 at 9:48 PM

I am truly saddened to hear about the death of Tim Russert today at the age of 58.  You'll see the Meet The Press feed in my blogroll.  I watched MTP every Monday during lunch.  Russert in interviews and during the Sunday broadcast showed himself to be a man of skill, intelligence, and most of all genuine integrity.  In a media landscape of extremes with Fox News and CNN as bookends he kept his personal opinions to himself and interviewed each guest thoroughly and impartiality.  I trusted him.  We have all lost one of the last true journalist.  He cannot be replaced, and his untimely death, particularly in this election season, is a great loss.

Comments [0]     Categories:               
Posted by Will on Thursday, June 12, 2008 at 4:11 PM

FamFamFam IconsThis another Frankenpost from the previous version of the blog, but I'm adding new content to the end.

Mark James over at FamFamFam has made available to the public a free set of 1000 icons (nope, that's not a typo) called Silk.  It's just one of three currently available.  As you can see from this preview, the icons are high quality.

Here's the new part:
The reason I found the FamFamFam collection was that I needed some icons for HappyFish.  I love the collection and have spent so much time looking at them that I can spot one instantly.  That's why when I updated my installation of twhirl I recognized one of the FamFamFam icons on a little dialog advertising a new feature.  ScrewTurn Wiki makes use of them too.  I'm going to be using ScrewTurn for the new HappyFish wiki.  As for twhirl, I recommend it as a desktop Twitter client.  It has integration with FriendFeed which is a nice bonus.

Comments [0]     Categories: Web Design | WinForms              
Posted by Will on Thursday, June 12, 2008 at 2:28 PM

This is a Frankenpost - it was on the blog before I migrated from Community Server to DasBlog.  It's one that I find useful so I'm porting it over.

Here's something I cobbled together as a replacement for a frameset. The technique takes advantage of the overflow CSS property applied to the HTML doc and a div within it to achieve the appearance of a frameset.  I used it in a MasterPage scenario, but it would work on a single page just as well. 

First you need to structure your page something like this:

<body >
    <form id="form1" runat="server">
        <div class="divHeader" id="masthead">
            This is the header
        </div>
        <div id="divPlaceHolderWrapper">
            <asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server" />
        </div>
    </form>
</body>

Your CSS should look like this:

body, html {
    overflow: hidden;
    font-family: Arial, Sans-Serif;
    margin: 0;
}

.divHeader {
    background-color: Gray;
    color:White;
    font-size: 2em;
    font-weight: bold;
}

#divPlaceHolderWrapper {
    overflow: auto;   
}

Hiding the overflow for the HTML has the effect of removing the scrollbar from the browser window.  We add it back to our div

And you'll need this JavaScript (which I found here):

<script language="javascript" type="text/javascript">
    function GetWindowHeight() {
        var myHeight = 0;
        if( typeof( window.innerWidth ) == 'number' ){
            //Non-IE
            myHeight = window.innerHeight;
        }
        else {
            if ( document.documentElement && ( document.documentElement.clientWidth ||    document.documentElement.clientHeight ) ){
                //IE 6+ in 'standards compliant mode'
                myHeight = document.documentElement.clientHeight;
            }
            else {
                if ( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
                    //IE 4 compatible
                    myHeight = document.body.clientHeight;
                }
            }
        }
        return myHeight;     }
    function SetPlaceHolderWrapperHeight() {
        var wrapperHeight = GetWindowHeight() - 37;  //the height of the lower edge of the browser window
        document.getElementById('divPlaceHolderWrapper').style.height = wrapperHeight + 'px';
    }   
    window.onload = function() { SetPlaceHolderWrapperHeight(); }
    window.onresize = function() { SetPlaceHolderWrapperHeight(); }
</script>

The resulting page will show the contents of the divPlaceHolderWrapper (in this case - whatever is in the content area of the page using this MasterPage) with a scrollbar if necessary.  If the content does not fill up the window, then no scrollbar appears.  While resizing the browser window in IE divPlaceHolderWrapper is continuously resized.  In Firefox the div is resized once the resizing of the browser window is complete.

Comments [0]     Categories: asp.net | CSS | Web Design