Improve Solution import time

Microsoft is investing a lot in advancements in the overall Application Lifecycle Management process and capabilities. One area they already made a lot of improvements is the Solution import time. In this blog post, we will discuss how this improved solution import time can be achieved.

Background

As mentioned Microsoft has improved the import time when it is done with the correct configuration. At one customer project, I was able to get our import down from usually 60 minutes to around 5 min.

What we have to do is use managed solutions and do an Update as well as have both “ConvertToManaged” and “OverwriteUnmanagedCustomizations” set to false time can be improved tremendously.

The question is what those two configurations do and why they improve the import time so much.

ConvertToManaged

As the name says it will convert components to Managed. This means when there is a component in your solution, which is already present in the target environment as unmanaged, it will be changed to a managed solution.

OverwriteUnmanagedCustomizations

When this configuration is set to true it will overwrite unmanaged customizations if there are any.

The reason why the import gets so slow when those are true is that the import engine has to loop through all components and compare them to the ones already present in the environment. When they are false the components will just get overwritten (with minimal changes) without comparing them.

Configuration

In this chapter, I will explain how this change is configured. There will be explanations for the “classic” UI and YAML. Both are for Azure DevOps pipelines, but could also be done in GitHub Actions.

The Maker portal does not have the option to change the mentioned parameters (there they are true with every import). Every tool that uses the API (MS Docs) is able to set those parameters. This means it not only is available in a pipeline (as I show it in this article) but also in some XrmToolBox Tools (or any other tool) such as the Solution Transferer.
Thanks to Tanguy Touzard (LinkedIn) for mentioning it to me.

YAML
- task: PowerPlatformImportSolution@2
displayName: Import Solution - ${{ solution }}
inputs:
authenticationType: 'PowerPlatformSPN'
PowerPlatformSPN: '<Name of your connection>'
SolutionInputFile: '<Path to your solution>'
ConvertToManaged: false
OverwriteUnmanagedCustomizations: false
AsyncOperation: true
MaxAsyncWaitTime: '60'
Classic UI

In the classic UI, it is important to mention that the naming of the configuration is incorrect. “OverwriteUnmanagedCustomizations” is correctly called “Overwrite unmanaged customizations”. The problem comes with “ConvertToManaged”, in the UI it is called “Import as a Managed solution”.

Optimization

As always there are ways of optimizing this process. As I mentioned earlier you should upgrade every once in a while. The best-case scenario would be to do this in the same pipeline. To achieve this we could add parameters to the pipeline. Those could be set on run time and change the behaviour of the pipeline.

Afaik this is only possible in YAML pipelines.

We would need 4 parameters:

  • Import as Holding Solution
  • Apply Upgrade
  • Convert to Managed
  • Overwrite Unmanaged
  - name: importHolding
displayName: Import as Holding Solution
default: False
type: boolean
values:
- False
- True
- name: applyUpgrade
displayName: Apply Upgrade
default: False
type: boolean
values:
- False
- True
- name: overwriteUnmanaged
displayName: Overwrite Unmanaged
type: boolean
default: False
values:
- False
- True
- name: convertToManaged
displayName: Convert to Managed
type: boolean
default: False
values:
- False
- True

The actual step also needs to be changed in a way that it is using the new parameters.

- task: PowerPlatformImportSolution@2
displayName: Import Solution - ${{ solution }}
inputs:
authenticationType: 'PowerPlatformSPN'
PowerPlatformSPN: '<Name of your connection>'
SolutionInputFile: '<Path to your solution>'
HoldingSolution: ${{ parameters.importHolding }}
ConvertToManaged: ${{ parameters.convertToManaged}}
OverwriteUnmanagedCustomizations: ${{ parameters.overwriteUnmanaged}}
AsyncOperation: true
MaxAsyncWaitTime: '60'

As you might have noticed we also have created a parameter to decide on whether to directly apply the upgrade. When this is set to true an extra step to apply the upgrade should be executed.

This parameter is needed, instead of applying it directly all the time, in case there is a need to do some manual steps (for example migration) before the upgrade is applied (and potentially components deleted).

Conclusion

To be able to apply the mentioned improvements you can’t use the maker portal for importing your solutions. When this prerequisite is met this advancement is easily implemented.

It is just important to use Update in combination with the correct configuration.

My recommendation is to run the mentioned configuration as your default and every “once in a while” (maybe once a quarter or so) run a “full-blown” upgrade where you also set the mentioned configuration to true. With this, you will still “clean up” your downstream environments.

I hope this article was helpful. If you have any questions do not hesitate to leave me a comment or get in touch with me.

This is just 1 of 59 articles. You can browse through all of them by going to the main page. Another possibility is to view the categories page to find more related content.
You can also subscribe and get new blog posts emailed to you directly.
Enter your email address to receive notifications of new posts by email.

Loading
2 Comments
  1. Avatar

Add a Comment

Your email address will not be published. Required fields are marked *