Tuesday, July 2, 2013

Upgrade custom workflow in SharePoint



Experience comes when you give a try or do something, I worked in to many SharePoint development project but my last project was troubled me during the deployment on staging server. I really interested to share the learning with all of you.

Recently we got an enhancement in one of our existing SharePoint project that has custom solution. The custom solution package contains workflows, application pages and InfoPath form. The site content was huge (25 GB), we got the site collection backup and restored on development environment and removed most of the contents to make more space on our development server. At the same time we got the requirement (enhancements) 1. Changes on one InfoPath form (adding additional fields) and one custom workflow (update in the workflow business logic and activities).

I have started the design of all enhancements but end of with major problem on the workflow. SharePoint does most of the things as per customer expectation but gives some pain to the developers and designers. Normally when we update and publish the SharePoint designer workflow, it creates a new version allow new instance on that new version and automatically not allows previous instances for new item. But this is a major issue in custom workflow. When user try to complete the existing workflow instances after updating the assembly, they may get "Task is locked by running workflow instance" error or it just hangs in "In Progress" state.. It is a very bad experience. I had read many articles which points the same issue.

If developer updates on the same DLL there are problems for existing items and there no way you can allow old workflow instances.  See the expected problems below.

  1. The old workflow DLL will be overwritten by new DLL in the GAC of deployment server
  2. If any changes done on the workflow activities then all “In progress” (old instances) workflow items cannot be completed.
  3. If changes done only on the business login then better to complete all “In Progress” workflow items before new DLL deployment.

I found a good article which explains above problem clearly, find some content and relates links below.



The following sections discuss three ways in which you can upgrade and version a workflow.

Option 1: Move all content to new site and re-execute incomplete workflows

You can create a new SharePoint site, register the new version of workflow on that site, and migrate list or document items that have workflows associated with them, omitting completed workflows. For items that have workflows pending, re-execute those workflows from scratch.

This option isn't great, because it requires data migration between the old SharePoint sites to the new SharePoint site. If your workflow fixes also modify the format of the underlying site (such as new fields in lists), the migration is nontrivial. Also, you have to re-execute your workflows that were not done, which adds burden on users who have already done their part to move workflow along.

Option 2: Code workflow so it can continue or restart all in-process workflows

For state machine workflows, you have an option of designing your state transition flow to accommodate possible future restarts. If your workflow process keeps some kind of state information in the list item or document properties, that state information is most likely a field in the list or document library. Your workflow probably expects a certain initial state value when it starts. A workflow that is already running would naturally have a different in-process state value.

If you code your workflow to accommodate any state value (not just the initial one) and during start-up jump to the code that executes that state, you can remove all completed and running workflows, remove the old workflow association with the old workflow assembly version, add a new workflow association with a new workflow version, and then re-execute all pending workflows.

Naturally, this approach puts a burden on you as a developer to add numerous conditional "re-entry/re-route" points to the beginning of your workflow. You may not want to do this extra work, or you may not be able to thoroughly test all re-entry scenarios. Also, this design is feasible for state machine workflows only.

Option 3: Run old workflows to completion with old assembly and new workflows with new assembly

You can change the mode of a workflow association to "No New Workflows," which stops new workflows from starting but allows existing ones to complete. By putting old workflow associations into "No New Workflows" mode and adding new workflow associations, you can have multiple versions of a workflow assembly running at the same time.

For example, you can have a workflow association named "MyCustomWorkflow v1.0.0.0" that is associated with version 1.0.0.0 of your workflow assembly in the "No New Workflows" mode. You can then add "MyCustomWorkflow v1.0.1.0" associated with 1.0.1.0 version of your workflow.

This is not the ideal solution either. For example, if the old workflow assembly has a bug that is not fixed, continuing to run the old workflow with the old assembly isn't helping you. Also, if the "On Item Change" event is enabled for the new workflow association, every time the item with the old workflow changes, it starts an instance of the new workflow. However, in some scenarios this approach remains the most valid.

Now, you need to deploy the new workflow assembly without removing the old version. Although stsadm.exe has the "upgradesolution" command, all it does is replace the old solution package with the new one. When the old solution package is removed, old workflow assembly will be removed from GAC as well.

To deploy a new workflow package over an old one

  1. Change the workflow assembly version.
  2. Change the workflow assembly version in the CodeBesideAssembly attribute of the Workflow element in Workflow.xml.
  3. Change the solution GUID in the manifest.xml file of your workflow project.
  4. Change the name of the .wsp solution package that is generated by package.ddfor rename the generated .wsp file.
  5. Deploy the new solution package alongside the old solution package, thus registering a new version of the workflow assembly in the GAC.
  6. Perform an IISReset command.
  7. Put the old workflow association into "No New Workflows" mode.
  8. Manually or programmatically create the new workflow association alongside the old workflow association, being sure supply a different name.