Here is a question that we answered in the interrupt slack channel afterwards OTA updates panel. We share the answer in our blog to make it available to a wider audience.
What is the best strategy to introduce incompatible changes in relation to update functionality, transport protocol, etc.?
For the starter, you have to version everything that can change so that you can actually find that there is a version change and can take the corresponding actions. There is a lot of complexity here, depending on what exactly you change and how backwards you have to be compatible.
In the live discussion, David Shoemaker mentioned support for pre- and post-update actions (e.g. executing scripts). This can be extremely useful to support actions such as data migrations or file removal that must be carried out after An update was completed. You can also use this ability to implement post-update string tests to ensure that the update processes are successfully completed. If the checks do not go on, they roll back to the previous version.
Depending on the incompatibility you introduce, you may have to divide updates into different phases that are introduced independently.
For example, let’s assume that you have an upcoming version that depends on a change in the update process. You first need an update that adds the necessary support to the new updater. After the provision, you would then introduce the dependent application update.
Another example of this is possibly turning the signature key. Let us consider the specific case in which the public key is baked into your boot loader. You create a boot loader with a new public key that is baked and sign it with your old private key. You will provide the bootloader update. Then you would sign your future updates with the new private key and the boot loader could decode it.