Category: Process and Planning

  • A basic deployment process for web apps

    Ah, deployment. That nervous moment when you release your code in to the wild to be used by, well, users.  You’ve done your part to test it yourself.  You’ve maybe even had a QA team or engineer take their best shot at finding bugs.  And now it’s time to kiss that baby good bye and promote it to the all grown up world of “Production”.

    Having a good strategy for deployment does two things.  First, a good repeatable process will ensure that anybody on the team should be able to issue a release.  This is important purely so you don’t get that call while you’re waiting in line at Sea World telling you that an emergency patch is needed and you have to guide the team through the release.  Secondly, a good deployment is prepared for the awful but very possible reality that you might have to abort the release and roll back to the current version.

    That said, here is a basic structure I use for preparing and deploying code.

    Get a clean build.
    This can come either from a build server, continuous integration platform, or a reliable developer’s system.  I primarily use Visual Studio, so I always Clean and Rebuild at the Solution level to ensure all the assemblies are refreshed.

    Create a label or tag to mark your code.
    For me, this is a basic audit trail so I have a timestamp of the release candidate version.  It also is a milestone from which I can merge to a Production branch if this release is the final version that goes live.

    Create your release package.
    Again, the actual packaging of your release can take several forms.  For some projects I use the Visual Studio ‘Publish’ feature, and have it output to the file system.  From there I’ll FTP the files to the production destination.  For other projects, we use a Setup package that creates an Installer.  This is mostly used when someone else such as a client is performing the deployment.  Pick a method that makes the most sense for your product, team, and production environment, and stick with it.

    Establish your release schedule.
    I tend to favor Friday night as a deployment timeframe mostly because it gives you the weekend to address any issues that may arise (when dealing with a business or corporate application).  Some of my clients do releases on Thursday mornings, others on Thursday nights.  There really is no right answer here, so again, find the most suitable time for your team and users and make it predictable.

    Put up a maintenance page.
    Depending on the size and effort required to execute the deployment, it may be necessary to put up a maintenance page informing visitors to your site that you’re making updates.  What you don’t want is people thinking your app is broken because they stumble upon it while your trying to release fixes or new features.  I love the ‘app_offline.htm’ file that IIS can use to show a maintenance page.  It’s simple, easy to customize, and is easy to turn off and on as needed.

    Back up code.
    Pulling a back up of your code pre-release is the contingency plan in case a rollback is needed.  It may or may not be necessary to back up every file, particularly if you have static or user-contributed content.  Ditto that for any log files that may be in your app.  But certainly the ‘guts’ of your app (meaning .DLLs, include files, etc.) and the ‘skin’ of your app (meaning any UI elements).

    Back up data.
    In many cases, if you have nightly database backups running, then the prior successful backup may be sufficient.  However, for highly transactional or critical data systems you may need to do an explicit data backup during your release window.

    Deploy code.
    FTP files across, or run the installer.

    Deploy data changes.
    Execute any database changes that are necessary using your database administration tool.

    Confirm.
    Confirming a successful release may simply mean checking a status page, or logging in and running through a series of transactions.  Your QA process will dictate what is required to verify a release in the production environment.

    Take down maintenance page.
    Rename the app_offline.htm file or otherwise set your app to live mode.

    Branch or merge in to Production code line.
    Now that you’re in Production, create or update a Production code branch with the code versions that have just been deployed so that you can address any production bugs without interfering with your ongoing development process.

    Announce your updates.
    In some form or another, let your users know what’s changed.  This might be a blog post, a status update, Tweet or email.  You’ve worked hard on this code and these features, so use this as a chance to get your users excited about using it.

    The process of releasing code to production will obviously vary according to the nature of your app, your user community, and your hosting or production environment.  But having a defined process will help make each release go smoother.

  • Picking a Mobile Web Strategy

    In the ongoing development roadmap for HomeSpot HQ is a simple item: Create a Mobile Optimized Site.  By itself, it is a pretty straightforward task.  We designed the HomeSpot HQ site for a 1024×768 browser window.  And while most of the modern mobile devices will render this site satisfactorily, there is definitely something about a truly optimized browsing experience when using the scaled down browser on an iPhone or (in my case ) Droid Incredible.

    Web or Native

    Our first strategic decision has been to focus first on an optimized website in lieu of a native mobile app.  There are plenty of reasons for leading with this approach:

    • the ability to leverage our existing code base vs. managing multiple code lines per device
    • broader device audience vs. per device versioning
    • avoiding deployment channels (and cost) via AppStore or Android Market

    As HomeSpot is an ASP.NET MVC application, I was able to use some guidance from Scott Hanselman about having a parallel set of Views for the mobile browser set that run alongside the default set of Views for the traditional browser set.  This approach allowed me to use my existing Controllers and (with a few exceptions) reuse the Models without modification.  Compared to rewriting in Java or learning Objective C to target their respective device platforms, this approach represented the fastest path to mobile coverage.

    Split or Common Site

    The other choice I made was to keep the mobile version and desktop version of the site under the same Url.  There are several pros and cons to this approach, and there may in fact be some ramifications I will have to deal with down the road.  So, the user experience will be such that if you view the site on a recognized mobile device, you’ll be served the mobile optimized Views, otherwise you’ll get the normal desktop Views.  The Url won’t change between the two versions.

    The advantages of this approach, so far as I have thought about them, include

    • easier deployment process with only one site to manage
    • unified Google Analytics

    However, there are some trade-offs:

    • lack of distinct Url such as “m.homespothq.com”
    • inability to easily deploy code fixes just to mobile site independent of main site
    • trickier to allow mobile users to view the non-mobile site if they so choose.

    Mobile Web Framework

    The final decision I chose to make was picking a mobile optimization framework.  I looked at iui and jquery mobile primarily, and decided to go with jquery Mobile.  While it is still emerging from an alpha stage, it appears to be meeting my expectations so far.  I’ll create additional posts with more specific commentary on this platform.

    The Mobile Optimized HomeSpot site is still under development and initial testing.  Given the limited time afforded to me to contribute to my own side-hustle, I hesitate to even offer a ship date.  Still, it has been a good exercise to weigh out the various options for reaching a mobilized audience.

  • Lessons learned from a great team.

    In the midst of transitioning to a new job, I felt it would be wise to take a minute to reflect on some of the lessons learned working with the talented team of developers at the North Carolina Housing Finance Agency.

    When I joined this team in August of 2009, they had recently gone through the departure of their department manager, and in response were adopting Agile as a development methodology. They faced the uphill battle of reestablishing trust among the other business units, and were in the process of migrating a legacy system in preparation for adding new features.

    In 16 months time, we completed the system migration, and delivered on two major business initiatives, earning high praise from both the end users and organization’s leadership. Additionally, we implemented and migrated our work to Team Foundation Server, conducted a pretty significant architectural overhaul, and doubled the size of our team as new work emerged.

    I feel proud to have been part of the team at NCHFA, and it is in their honor that I share these lessons learned. I hope to be able to apply these lessons as necessary with the team I am joining.

    1. Planning and prioritization is a daily discipline. Nearly every activity our team spent time on fell in to one of the following categories of planned work:

    • In-Sprint project work – tasks specifically contained in our Agile sprint.
    • Helpdesk items – end user support of our production systems, under 40 hours
    • Pipeline items – projects in excess of 40 hours of work
    • BPI (Business Process Initiatives) – multi-project initiatives in excess of 100 hours of work.

    Every week, in a standing, Monday at 10am meeting, our entire team would provide status and updates on all work across these categories.  This simple practice of routinely reviewing, re-prioritizing and re-assigning work as necessary allowed every member of our team, as well as our management to have a complete picture of the entire team’s workload and progress.

    2. Trust the process of debating an issue. During our sprint planning, and especially during the lead up to re-architecting our systems, there were many instances when we as a team didn’t always see eye to eye.  More than any other team I have been a member of, the level of honest and respectful debate that we had was significant to our success.

    3. Start manually, then automate. There is no lack of tools to help teams manage the Agile software development process.  But for nearly the first year of working together, our team relied on index cards and sticky notes.  By adhering to a fully manual process, it allowed our team to work out the necessary adaptations and adjustments to our usage of Agile and become experts both individually and collectively of the methodology.  At the point in time when we elected to implement a project management tool, in our case Microsoft Team Foundation Server 2010, we knew how to run our sprints and manage our stories so well that adopting the tool was nearly effortless.  The result is that our usage now of TFS was able to take full advantage of its features for planning, reporting and tracking our progress.

    4. Demonstrate your results across the organization. With few exceptions, we provided an open invitation to the entire organization to attend our end of sprint product demonstration.  In these meetings, we used a few Powerpoint slides to review all our previous sprints, which reminded the business groups of the overall project progress and decision points along the way.  We then gave a full, live demonstration of the new functionality we delivered in the last sprint.   By showing our progress along the larger project timeline on a routine basis, our team established a significant level of trust from the business groups.  We simply let our delivered, working code speak for itself.

    It was my pleasure to be part of the team at NCHFA, and I look forward to hearing from them about the results they will continue to produce in the months to come.  Congratulations to Joe, Tim, Dan, Eric, Steve, Dev and Jaime for all you’ve achieved over the last year.

  • TFS Migration: Sharing common code

    In this latest installment of recording our team’s migration to Team Foundation Server 2010, I’ll be describing how we organized and share our common code libraries.

    The scenario is quite common. We have a Application that provides specific line of business functionality. It leverages several Common libraries that provide underlying functionality that are used by all of the Applications built and supported by our team.

    Previously, when using Visual SourceSafe, we would share these libraries by using the ‘Add Project from Source Control’ feature in Visual Studio to add the common projects to our Application’s solution.

    TFS guidance offered several approaches to sharing these libraries across Applications. The primary approaches are:

    1. Workspace Mapping – add a directory mapping to your workspace for the shared library so it will be updated to your local box alongside your application’s directory structure. This is essentially a client-side solution, since Workspaces are managed on the local development system.
    2. Branching and Merging – use the improved Branching capability in TFS to branch the common project into the source control structure of the application project. This is essentially a server-side solution, since the branched code is maintained by Source Control and will be updated by anyone who does a ‘Get Latest’ on the project directory.

    We have adopted the Branching and Merging approach, but it was not without a lot of experimentation of both methods. In the end, here were the key factors in our choice.

    1. Server side vs. client side. A big part of our goal in organizing our projects is the ability to set up a new development environment quickly. The server side Branch and Merge strategy supports this goal by eliminating one more step (that is, configuring the Workspace) in preparing a new dev environment.
    2. Isolation of potential changes. While it is more and more infrequent, changes do occur to the common libraries. By leveraging a Branch, the branched copy of the common project is isolated from all other consumers of that library, until the changes are merged in to the Main branch for the common library. If we were using the Workspace mapping approach, a check-in of changes would go straight to the Main branch of the shared project, which could cause a ripple effect through other Applications that are using the common code.

    Still, there are other implications and adjustments for our development team, primarily propogating changes. In the case when a change to a common library is merged back to the Main branch, and it is appropriate to propogate those changes to all other consumers, a new effort is required to forward merge the common code out to its consumers. This effort is compounded if the consumer Application itself has multiple branches that would all need the updates. However for our team, this is an acceptable trade off since a) changes are infrequent, and b) the number of consuming applications is manageable. Furthermore, as we continue to expand our automated Build setup, propogation may be something that can be scripted in as part of a nightly build of the common projects.

    For more information about these approaches, you can check out the Patterns & Practices guidance for Team Development with TFS.

  • TFS Migration: Branching and Merging Strategy

    As we are evaluating and planning our migration to Team Foundation Server 2010, considerations for adopting a Branching and Merging strategy for our source control projects has demanded a lot of our attention.

    While using Visual Source Safe, our team rarely if ever used Branching to isolate project so they can be developed or supported in parallel with our main effort. VSS wasn’t so great at executing branching and merging, and we, like many, chose to err on the side of caution and forego branching altogether.

    In TFS Source Control, it seems branching and merging have been improved to a level of comfort where we as a team can have some confidence that executing a branch or merge operation won’t lead us to spend more time cleaning up rather than moving on and doing the development work itself.

    In the end, we have largely concluded to use branches to isolate our releases, but not to isolate our normal development during a sprint. As such, our Main (or Trunk) branch will be the primary (and consequently slightly unstable) code line. After each release, we will create a branch for that deployed version of the product for maintenance purposes.


    Here are some of the key factors in our decision:

    1. branches require a level or “care and feeding” that (for our relatively small team, at least) would have not yielded any great value for our normal development sprint. We rarely have divided teams working on the same product, or long running feature development in parallel to working our product backlog.
    2. branching complicates IIS hosted applications. We choose to use IIS, rather than the Visual Studio Development Server, to host our applications during development. Consequently, every branch requires a reconfiguration of IIS to point to the site’s directory contained in that branch. While this reconfiguration be scripted (as demonstrated here) it still is another step that the developer has to remember to perform.
    3. branching is further complicated when you have shared code libraries that must be replicated to every new branch. While there are some clever approaches to managing workspaces or using Build scripts to update branches, you can alleviate the whole issue by minimizing the branches you create.
    4. we do not have a formal QA team that would require a stable Main branch for testing purposes. Our adoption of Agile is such that our peer reviews and testing are integrated in to our sprint, and consequently we are not ‘handing off’ our product to another team to exercise. If there were a QA team, then it certainly would be more important to keep a highly stable Main branch, and that would merit spawning a new Branch for ongoing development. In our case, it’s just not necessary.

    It is nice to know that TFS Source Control makes branching and merging a more trustworthy operation, and that the tools are there when we need them. But for now, we’ll take the simple road.

  • TFS Migration Resources

    As I am doing research and preparing for our migration to Team Foundation Server, lots of various resources are emerging to assist in our planning. It seemed appropriate to make a list of these items and provide some commentary on their content and relevance to our efforts.

    Codeplex based resources
    patterns & practices Team Development with TFS Guide (Final Release)
    This online guide provides a decent overview of how to leverage TFS for your development team. While it has not been updated (so far as I can tell) to reflect TFS 2010, many of the concepts and descriptions are relevant and applicable with the latest version of the product.

    Visual Studio TFS Branching Guide 2010
    One of the major choices we are facing in the midst of our migration is whether to move into using branching and merging as part of our development process. The guides provided by the so-called ‘Visual Studio ALM Rangers’ give very clear overviews and explanations of the various strategies surrounding branching your code and organizing your project.

    MSDN based resources
    Team Foundation Server 2010 Resources page
    MSDN, true to its mission, provides plenty of source material about TFS directly from Microsoft. You can start with the TFS Installation Guide, then move to the Getting started with Visual Studio Application Lifecycle Management to get a good basic understanding of the parts and pieces that make up the TFS product.

    Blogs

    The Woodward Web
    Brian Harry – Brian Harry was one of the original developers of SourceSafe, and is now part of the Team Foundation Server product team at Microsoft.

    As I find additional resources, I’ll update this list.

  • Migrating to Team Foundation Server 2010: Preamble

    About a year ago, I led an effort to introduce the organization where I work to automated unit testing, continuous integration and automated deployment as part of the development process. We implemented CruiseControl.NET, wrote and refined dozens of NAnt scripts, and in the end, established a working CI environment for our project, complete with nightly builds, one-click deployment to our test environment, and execution of NUnit tests, code analysis and creation of API documentation.

    This year, Microsoft released Visual Studio 2010, and with it a new release of Team Foundation Server, and our team has all come together to work towards implementing TFS into our environment. With that implementation, the existing CruiseControl.NET build environment will give way to TFS Build, and I will use this blog to document and share the planning, process and lessons learned as part of migrating a medium sized application in to TFS as Team Projects.

    In the coming weeks, we’ll be making decisions about things such as:

    1. How to structure our projects in TFS Source Control.
    2. How to organize our Solutions and Team Projects.
    3. How to map our current CI process to the TFS Build workflow.
    4. How to manage our Agile/Scrum process using TFS Work Items.

    As a prelude, here’s a brief overview of the application we’re working with.

    Ours is an intranet application for project management and workflow handling. The basic structure follows a n-Tier architecture, though we are using Dependency Inversion. The component parts include:

    • An ASP.NET Web site project
    • A Utility library for common functions.
    • A DataAccess library for database access.
    • A Workflow library for common workflow functions.
    • A Core library, defining our business entities, data access interfaces, and service methods.
    • A Data library, which implements our actual database calls.
    • A Controller library, which is a go-between for the Web Site pages and our Core layer.
    • 2 libraries containing integration to 3rd party product APIs.
    • Several unit Test libraries for the Core, Controller and Workflow libraries.

    All told, our Visual Studio solution contains 16 projects.

    We also have a project containing our common NAnt build scripts and CruiseControl.NET configuration files, and each individual project has a NAnt build script governing the build for that assembly.

    The Utility, DataAccess and Workflow assemblies are shared with other applications.

    Finally, we have about a half-dozen 3rd party Assemblies that we use, which includes the Microsoft Enterprise Library, Telerik UI controls, and Aspose Word.

    In planning our migration, we must be able to continue to allow the Shared Assemblies to be accessible and used by other projects, as well as maintain all the functionality NAnt and CC.Net provides.