Demystifying upgrade process for Business Central Apps
This is the second blog post on series.
The beginning is here Demystifying installation process for Business Central.
...In the previous series
We ended up with the summary: what's going on during the first-time installation of the app.
- Upgrade codeunit was not triggered at all. That’s because we publish our app for the first time.
- Install codeunit was triggered.
The result of this scenario can be displayed in the next picture
Figure 1. Install app for the first time
SCENARIO 2. Upgrading App
When you want to add some features or fix bugs you need to change the version of your app. With this simple approach, you will have transparency in what version has what functionality.
The official documentation is here.
But before we upgrade
When you write upgrading business logic two questions appear
- What app version is already installed?
- What app version is installing?
We need this to understand if current upgrade business logic is compatible with the already installed app.
For example, we want to populate data in the new Address field, while upgrading an app to v.2.
So we add something like
codeunit 50100 "Upgrade App" { Subtype = Upgrade; trigger OnUpgradePerCompany() begin PopulateNewAddressField(); end; local procedure PopulateNewAddressField() var Customer: Record Customer; begin With Customer do begin if FindSet() then repeat "New Address" := 'some value'; Modify; until next = 0; end; end; }
If you will leave this code as is, and upgrade to V.3 - this code will also be executed, which would be an unexpected result for everybody.
NAVApp and ModuleInfo will help
To avoid this situation we need to create separate upgrade codeunit for each version. So previous code could be refactored to next one
codeunit 50100 "Upgrade App to v2" { Subtype = Upgrade; trigger OnUpgradePerCompany() begin If not CheckIfInstallingAppVersionCompatibleWithInstalledVersion() then exit; PopulateNewAddressField(); end; local procedure CheckIfInstallingAppVersionCompatibleWithInstalledVersion() : Boolean begin Exit((GetInstallingVersionNo() = '2.0.0.0') and (GetCurrentlyInstalledVersionNo() = '1.0.0.0')); end; procedure GetInstallingVersionNo(): Text var AppInfo: ModuleInfo; begin NavApp.GetCurrentModuleInfo(AppInfo); exit(FORMAT(AppInfo.AppVersion())); end; procedure GetCurrentlyInstalledVersionNo(): Text var AppInfo: ModuleInfo; begin NavApp.GetCurrentModuleInfo(AppInfo); exit(FORMAT(AppInfo.DataVersion())); end; local procedure PopulateNewAddressField() var Customer: Record Customer; begin With Customer do begin if FindSet() then repeat "New Address" := 'some value'; Modify; until next = 0; end; end; }
With ModuleInfo you get info about your app.
- DataVersion tells you what version is currently installed
- AppVersion tells you what version are you installing
Let's upgrade begins
We will just increase version and install the app once again.
app.json > “version”: “2.0.0.0”
Container Sandbox
VSCode > AL:Publish without debugging (Ctrl+F5)
And we receive next error
Ok, let’s run this command Start-NavContainerAppDataUpgrade
Start-NavContainerAppDataUpgrade -containerName $containername ` -appName $appname
And will have a look at the installation log
Online Sandbox
VSCode > AL:Publish without debugging (Ctrl+F5)
And we receive next error
Frankly speaking, I did not find a solution how to run Start-NAVAppDataUpgrade for the Online Sandbox.
But there is a workaround. If I will go to the Extensions page on Online Sandbox will see v. 2.0.0.0 app - published, but not installed.
I just click Install from web UI, and it’s done.
And will have a look at the installation log
Online Business Central Production Tenant
>Web client > Extensions Page >Upload .app file
And without any errors, we get the same picture
Upgrading app. Summary
- Upgrade codeunit was triggered. That’s because we publish our app for the second time with increased version id.
- Install codeunit was not triggered. That's because we changed the version of our app. This is what official documentation says
Install codeunit provides a set of triggers that are executed when the extension is installed for the first time and when the same version is re-installed
The result of this step can be displayed in the next picture
Figure 2. Upgrading app
What's next
Next blog will be about the re-installation process. Stay tuned.
Comments
-
And after I read the post once again, I noticed that they are _not_ identical, the first one uses AppVersion and the second one DataVersion as you noted below the blog. :-E
-
Hello Dmitri! I want to thank you for this great chain of posts, it has been of a great help for me. I tried your approach of using version checks, but I noticed that GetInstallingVersionNo and GetCurrentlyInstalledVersion functions are identical. So I suspect that they both return the currently installed version no. What should be the correct way to get both versions, the currently installed one and the one I am trying to install?
-
Hey Dmitri, thanks for the article! Unfortunately, I seem to be unable to run any of the upgrade code I've put in place on my Dynamics 365 BC Docker. I was under the impression that the code would execute itself as you seemed to be hinting at. Unfortunately, no matter how I increment the extension version, I am unable to debug my code or have any kind of result show up in my Docker. Am I missing something? Do I need to execute my upgrade code through Powershell when dealing with a Docker? In any case, thanks in advance for any help you could give me! Sébastien Lehoux
-
Great series, Dmitry. Tip: you might want to update this post with links to all follow up post.
-
*This post is locked for comments