In this post we will package and deploy a Globally Reusable Workflow using a Visual Studio 2010/2012 project, once built the workflow will be activated using a feature. We will not discuss creating, customizing or designing workflows as this is covered more than adequately all over the internet.
- How to: Import and Package a Declarative Workflow in Visual Studio
- How to: Create and Deploy Declarative Workflows in Sandboxed Solutions
- Introduction to designing and customizing workflows
Types of Workflow
A reusable workflow is a workflow which may be reused across lists or libraries within a site contained by a site collection. This type of workflow may exist at a sub site or the site collection root web, but may only be used at the site in which it was published.
A reusable workflow is stored in a site in a hidden library called Workflows (SPListTemplateType = 117) which is intended for declarative no-code workflows. This library has no views and can only be viewed using SharePoint designer (All Files ~ Workflows)
Globally Reusable Workflow
A globally reusable workflow is a workflow which may be reused across lists or libraries within all sites contained by a site collection. This type of workflow exists at the root web of a site collection in the Workflows catalog (_catalogs/wfpub).
In both cases, the workflow files themselves are stored in a sub-folder with the same name as the Workflow.
Create a Globally Reusable Workflow.
In SharePoint Designer, open the root web of a site collection and create a Reusable Workflow, add your workflow logic and then save and Publish Globally.
To package the workflow in Visual Studio we will export the workflow as a template and then import the resultant .wsp into Visual Studio. However, a Globally Reusable Workflow cannot be saved as a template, in order to do this we must copy the workflow (to a reusable workflow) and save the copied workflow as a template.
In the main Workflows navigation pane of SharePoint Designer, select the Globally Reusable Workflow and choose the Copy & Modify command from the ribbon – this copies the workflow as a reusable workflow.
Having done this, open the newly copied reusable workflow, Save then Publish it – don’t publish this one Globally.
Back in the main Workflows navigation pane of SharePoint Designer, select the newly copied and published Reusable Workflow then choose the Save as Template command from the ribbon – this will save the workflow as a template to the Site Assets library in the root web of the site collection.
Download this file from Site Assets to your local disk.
Import into a Visual Studio Project
Open Visual Studio 2010 or 2012 and create a new project.
Select the Import SharePoint Solution Package project template – do not choose the Import Reusable Workflow project template as this will convert the imported workflow into a coded workflow.
Follow the project template prompts, which includes selecting the workflow template (.WSP) file created earlier.
When prompted to select the assets in the .WSP to import, select only the Workflow (Module) item and not the Workflows (List Instance) item – remember, to save the workflow as a template we had to copy it as a reusable workflow, which meant that it was published to the Workflows library. Since we’re trying to package a Globally Reusable Workflow (which will be deployed to _catalogs/wfpub), we’re not interested in the Workflows library.
After the project template wizard completes, your solution should look like this (unless you’re using Visual Studio 2010 🙂
Note: In my project above I’ve added a feature and elements file for deploying a ContentType & Site Columns which this particular Workflow is restricted by, as shown below in SharePoint Designer.
Project Fixup Steps.
Now for some grungy fixups;
Change the scope of the Workflow feature to Site scoped.
Replace all instances of workflows/ with _catalogs/wfpub/ throughout the entire solution, use *.* as the file mask.
_catalogs/wfpub is the virtual directory in which global declarative workflows are stored in a site collection.
Workflows is the document library in which site level (Reusable Workflows) are stored
Open the .xoml.wfconfig.xml file for the workflow:
- In the <Template> element, change the value of the Visibility attribute to RootPublic
- In the <Template> element, change the value of the DocLibURL attribute to _catalogs/wfpub
- In the <Instantiation> element, ensure that _catalogs/wfpub starts with a leading /
e.g. /_catalogs/wfpub/IMPRetention/IMPRetention.xsn, see below (this step is missing from the reference article)
Next, open the elements.xml file for the PropertyBags module.
- Remove the PropertyBag nodes for the Workflows listinstance
- Locate the PropertyBag node for the .xoml.config.xml file and change the value of the NoCodeVisibility property to RootPublic (see below)
At this point you’re ready to build, package and deploy, however you might want to take the time to cleanup the project a bit, remove some of the folder nesting of the Workflows module and so on.
All you need do now is to build and deploy the solution, then go associate the workflow with some list or content type, ensure too that you test this at sub-sites – its supposed to be globally reusable after all.
If the workflow is restricted by Content Type (as mine was in this example), the content type Id is referenced in the workflows .xoml.wfconfig.xml file in the Category and ContentTypeID attributes of the <Template> element as shown below;
The content type Id is also mentioned in the RestrictContentTypeId meta attribute of the MetaInfo property of the <File> element for the workflows .xoml.wfconfig.xml in the Module which provisions this file
And lastly the content type Id is also referred to in the RestrictContentTypeId property of the <PropertyBag> element for the the workflows .xoml.wfconfig.xml file;