Swap out old code-components with new using the Power Platform CLI

If you have canvas apps that use code components then you will be used to the hard link between the namespace of the code component and the canvas apps that use it. Also, if you have your canvas apps in a solution, then there are now solution dependencies added for the code components used to ensure that they are installed before you import the solution to a target environment. You can read more about code component ALM in the Microsoft docs.

How do we swap out components easily?

Occasionally, you may need to change the namespace of a control (or perhaps change a property name) but it is very time-consuming to remove the control from all the apps, then re-add it after the update. This is especially painful if you have lots of Power Fx code referencing it.

Power Apps CLI to the rescue

I have long been an advocate of storing everything as code - and canvas apps are no exception here. The once experimental canvas app sopa tool (Power Apps as source code) is now all grown-up and is included in the Power Platform CLI. 😊

In this post, I am going to show you how to take a solution, unpack it, update the code components, and then re-pack so that they will use the new components. This is made possible largely by canvas apps now being unpacked into Power Fx.

Step 1 - Export your solution

Export your solution that contains the canvas apps - but don't include the code components. Let's imagine you have two apps that both use two code components and the solution is named MyAppsSolution.zip.

Step 2 - Unpack your solution

Make sure you have the Power Platform CLI installed - I find it really easy to use the Power Platform Tools VSCode extension.

Using PowerShell (assuming you are in the root folder that contains the solution zip):

pac solution unpack --zipfile MyAppsSolution.zip --folder Solution

This will create a folder named Solution that contains all the unpacked elements. There will also be a folder named CanvasApps that contains the msapp files and the corresponding metadata for your apps.

Step 3 - Unpack the canvas apps to Power Fx

Now we can unpack are two apps into the Power Fx that we will need to edit. There are lots of files created in addition to the Power Fx source code that contains metadata about the elements used in the app.

Using PowerShell (assuming you are in the root folder that contains the solution zip):

Get-ChildItem -Recurse -force -Path $dir | where-object { $_.Extension -eq '.msapp' } | ForEach-Object { 
    pac canvas unpack --msapp $_.FullName --sources "CanvasAppsSrc\$($_.BaseName)"

You will now how your Power Fx source for each of your apps under the CanvasAppsSrc folder!

There is an entropy folder that is created for round-trip rebuilding, but we can safely delete these folders using PowerShell:

Get-ChildItem -Recurse -Directory -Path $dir | where-object { $_.BaseName -eq 'Entropy' } | ForEach-Object { 
    Write-Host "Removing Entropy Folder $($_.FullName)"
    Remove-Item $_.FullName -Force -Recurse

Step 4 - Search/Replace

This step is the more tricky part - we need to change all the references to the code component's old namespace/solution prefix and replace it with the new one. This is easier if you have names that are unique!

Open up the root folder in VSCode and use the global search and replace function (with case sensitivity turned on) to preview what you are doing. You will find the replacements needed in jsonyaml and xml files.

Step 5 - Rename files

When changing the namespace/publisher prefix of your code components, it is also necessary to rename the resource files that are part of your code components since each file is prefixed with the namespace. Additionally, the app resource file names are prefixed with the solution publisher.

You can use the PowerShell:

$oldnamespace = "Samples";
$newnamespace = "MyNamespace"
$oldpublisher = "samples_";
$newpublisher = "myprefix_"

Get-ChildItem -Recurse -force -Path $dir | where-object { $_.Name.StartsWith($oldnamespace) } | ForEach-Object {
    rename-item -LiteralPath $_.FullName $_.FullName.Replace($oldnamespace,$newnamespace) 
Get-ChildItem -Recurse -force -Path $dir | where-object { $_.Name.StartsWith($oldpublisher) } | ForEach-Object {
    rename-item -LiteralPath $_.FullName $_.FullName.Replace($oldpublisher,$newpublisher) 

Step 6 - Repacking

You can now re-pack the apps and the solution!

Get-ChildItem -Recurse -force -Path $dir | where-object { $_.Extension -eq '.msapp' } | ForEach-Object { 
    pac canvas pack --msapp $_.FullName --sources "CanvasAppsSrc\$($_.BaseName)"

pac solution pack --zipfile UpdatedSolution.zip --folder Solution

Step 7 - Update code components & Import solution

Ensure that you have published the new versions of your re-build code components to your environment making sure to increment the control versions. It is very important to increment the version of the code components so that the canvas apps will detect the new version upon opening up after the update. This will force the update to the new code-component resource files.

You can now import the UpdatedSolution.zip into your environment.

When you open each canvas app you will get the upgrade component prompt and your app will be using the new code components under the updated namespace!

If you updated the code-component resource files then theoretically you could perform the same on a managed solution and remove the need to open and republish each app, but I've not tried this!

Hope this helps!



Comments are closed