Previously, when an entity was added to a solution and that solution was exported, the entity and all of its assets were exported in that solution. This included attributes, forms, views, relationships, visualizations, and any other assets packaged with the entity. All objects were exported regardless of whether the developer actually wanted to ship the object. This process potentially carried dependencies or modified unintended objects on the target deployment.
Now, we can create and publish solution patches that contain subcomponents of entities, as compared to publishing the entire entity and all of its assets. The original solution and multiple released patches can be rolled-up at a later time into an updated version of the original solution, which then can replace the original solution.
Patches
We can apply patches to either managed or unmanaged solutions and include only changes to entities and related entity assets. Patches do not contain any non-customized system components or relationships that it dependents upon because these components already exist in the deployed-to organization. At some point in our development cycle, we can roll up all the patches into a new solution version to replace the original solution that the patches were created from.
Patches are stored in the CRM database as Solution entity records. A non-null ParentSolutionId attribute indicates that the solution is a patch. Patches can be created and managed through the Organization Service or Web APIs, which are useful for developing automation such as a product install script. However, the CRM web application provides various web forms that enable us to interactively create and manage patches.
- Patches can only be created from a parent solution using CloneAsPatchRequest or CloneAsPatch Action.
- The patch parent can’t be a patch.
- Patches can only have one parent solution.
- A patch creates a dependency (at the solution level) on its parent solution.
- We can only install a patch if the parent solution is present.
- We can’t install a patch unless the unique name and major/minor version number of the parent solution, as identified by ParentSolutionId, do not match those of the parent solution installed in the target organization.
- A patch version must have the same major and minor number, but a higher build and release number, than the parent solution version number. The display name can be different.
- If a solution has patches, subsequent patches must have a numerically higher version number than any existing patch for that solution.
- Patches support the same operations as solutions, such as additive update and removal.
- Patches exported as managed must be imported on top of a managed parent solution. The rule is that patch protection (managed or unmanaged) must match its parent.
- Don’t use unmanaged patches for production purposes.
- Patches are only supported in CRM organizations of version 8.0 or later.
The SolutionPackager and PackageDeployer tools support solution patches.
Create a patch
Create a patch from an unmanaged or managed solution in an organization by using the CloneAsPatchRequest message or the CloneAsPatch Action, or by using the web application. Once we create the patch, the original solution becomes locked and we can’t change or export it as long as there are dependent patches that exist in the organization that identifies the solution as the parent solution. Patch versioning is similar to solution versioning and specified in the following format: major.minor.build.release. We can’t make changes to the existing major or minor solution versions when we create a patch.
Export and import a patch
We can use the Organization Service or Web APIs, the web application, or the Package Deployer tool to export and import a patch. The relevant Organization Service message requests are ImportSolutionRequest and ExportSolutionRequest. The relevant actions For the Web API are ImportSolution Action and ExportSolution Action.
Patching examples
The following table lists the details of a patching example. Note that in this example, the solution and patches are imported in order (version 1.0 to 1.0.2.0).
Patch Name | Description |
SolutionA, version 1.0 (unmanaged) | Contains entityA with 6 fields. |
SolutionA, version 1.0.1.0 (unmanaged) | Contains entityA with 3 fields ( -3 ) and adds entityB with 10 fields. |
SolutionA, version 1.0.2.0 (unmanaged) | Contains entityC with 10 fields. |
The import process is as follows.
- The developer or customizer first imports the base solution (SolutionA 1.0) into the organization. The result is entityA with 6 fields in the organization.
- Next, the SolutionA patch 1.0.1.0 is imported. The organization now contains entityA with 3 fields plus entityB with 10 fields.
- Finally, SolutionA patch 1.0.2.0 is imported. The organization now contains entityA with 3 fields, entityB with 10 fields, plus entityC with 10 fields.
Delete a patch
We can delete a patch or base (parent) solution by using DeleteRequest or, for the Web API, use the HTTP DELETE method. The delete process is different for a managed or unmanaged solution that has one or more patches existing in the organization.
For an unmanaged solution, we must uninstall all patches to the base solution first, in reverse version order that they were created, before uninstalling the base solution.
For a managed solution, we simply uninstall the base solution. The CRM system automatically uninstalls the patches in reverse version order before uninstalling the base solution. We can also just uninstall a single patch.
Update a solution
Updating a solution involves rolling up (merging) all patches to that solution into a new version of the solution. Afterward, that solution becomes unlocked and can once again be modified (unmanaged solution only) or exported. For a managed solution, no further modifications of the solution are allowed except for creating patches from the newly updated solution. To rollup patches into an unmanaged solution, use CloneAsSolutionRequest or the CloneAsSolution Action. Cloning a solution creates a new version of the unmanaged solution, incorporating all its patches, with a higher major.minor version number, the same unique name, and a display name.
For a managed solution things are handled slightly differently. We first clone the unmanaged solution (A), incorporating all of its patches and then exporting it as a managed solution (B). In the target organization that contains the managed version of the (A) solution and its patches, we import managed solution (B) and then execute DeleteAndPromoteRequest or the DeleteAndPromote Action to replace managed solution (A) and its patches with the upgraded managed solution (B) that has a higher version number.