App Dependency Tree – import your apps in the right order (with PowerShell)

Recently, I got the question on how to get a dependency tree from a bunch of Microsoft Dynamics 365 Business Central apps. In other words – how do I know in which order I have to import my apps to respect the dependencies.

Well, I didn’t have a ready-made script available. I only had a script my colleague provided me – so I took that as a starting point, and spent an evening in trying to put something together – as it IS a very interesting question ;-).

To be honest, we don’t need this in our company in our build pipeline, nor in our release pipeline. Nevertheless – I have heard the question multiple times, so Let’s .. Get .. Started .. ;-).

PowerShell

It’s obvious we will use PowerShell for this, as that’s what you will use to publish apps in an environment. You use it in build pipelines, in release pipelines, and even when you would just import in a one-off sandbox.

In PowerShell, we also have the CmdLets that Microsoft provides to manage our environment.

So .. Let’s start by linking the script, which you can find on my GitHub here: https://github.com/waldo1001/Cloud.Ready.Software.PowerShell/blob/master/PSScripts/NAV%20Extensions%20v2/GetDependencies.ps1

(I’m just providing a link, as when the script would change, you would alway see the up-to-date version of the script).

Some brief explanation

The script assumes you have a bunch of app-files somewhere. In this case, on the “c:\programData\NavContainerHelper” folder, because I’m using docker in order to run Business Central PowerShell CmdLets. You see I’m using the “Get-NAVAppInfo” cmdlet to get information about my apps. This information includes dependencies – which I will obviously need for my script. I then create my own collection of apps in PowerShell to be able to loop and do my thing.

The function AddToDependencyTree is a recursive function (wow – I didn’t use recursive functions for ages :-/) where all the “magic” happens. By looping the apps in my collection, I will always respect the dependencies by recursively drilling down into the dependency tree, and handle the lower-leveled apps by adding (or modifying) them with a lower “order” in the result-array (the DependencyArray variable).. . When completely looped, I have a new array including a decent “ProcessOrder” property in my collection.

On the bottom of the script, you see the actual loop, where I loop all the apps, and add them to the dependency tree.

Test

To make it somewhat easier for me, and to simulate a somewhat complex dependency tree, I created this script:

https://github.com/waldo1001/Cloud.Ready.Software.PowerShell/blob/master/PSScripts/NAV%20Extensions%20v2/GetDependencies_TestApps.ps1

It would replace the “Get-NAVAppInfo” looping through files, as it will build a “$AllApps” variable to be able to loop through.  Just a tip ;-).

Disclaimer

I did briefly look online if I could find any blogpost that already handled it – but only briefly. If I missed a solution (which is probably better than this one) – I apologize. There are so many contributors lately, it’s hard to keep track, catch up, … you know what I mean ;-). So, if you have a better (or worse ;-)) solution, don’t hesitate to mention that in the comment section.

Enjoy!

4.80 avg. rating (95% score) - 5 votes

Permanent link to this article: https://www.waldo.be/2019/08/28/app-dependency-tree-import-your-apps-in-the-right-order-with-powershell/

21 comments

6 pings

Skip to comment form

    • Hilmar on August 28, 2019 at 7:24 am
    • Reply

    Hi Waldo

    I think you accidentally linked to the same script twice.

    I believe the link to the “Test” script should be the following

    https://github.com/waldo1001/Cloud.Ready.Software.PowerShell/blob/master/PSScripts/NAV%20Extensions%20v2/GetDependencies_TestApps.ps1

      • waldo on August 28, 2019 at 9:08 am
        Author

      Thanks for mentioning! I updated the article :-).

    • marknitek on August 28, 2019 at 7:30 am
    • Reply

    Could you explain why you don’t need it in your company? Do you have a monolith app or another solution to the problem?

      • waldo on August 28, 2019 at 9:06 am
        Author

      Well, we have a repository per app, having its own build pipeline.
      For apps with dependencies, we set up the download of the latest artifact, to get the symbols for compiling.
      for apps that has other apps depending, we set up a trigger to start building the app that depends on “me”.

      It works like a charm, and in my opinion, it’s actually better then having all these “hard” dependencies: I shouldn’t fail a build of app A, just because I broke B by changing A. May be I shouldn’t release A and B to my environment when B is broken, but I should be able to release A to another that doensn’t have B.

      Breaking a dependency is a problem for the app that depends on the other, not for the one that is independent. Just Microsoft’s BaseApp in account – same reasoning.

      It’s how we want to handle dependencies (or “independencies” if you will ;-)). Meaning: I won’t compile, import, all apps at the same time. They are all part of a release pipeline, which handles it without needing the dependency tree.. .

      That’s at least my opinion of today .. might change in the future ;-).

      • waldo on August 28, 2019 at 9:07 am
        Author

      And .. we definitely have no Monolith – far from it ;-). One product was divided in 11 apps ;-).

    • Dennis Reinecke on August 28, 2019 at 12:03 pm
    • Reply

    Thanks for sharing!

    We using something similar in our company (inhouse – around 20 different apps per database installed).
    I want to give you an example how we use it.
    When ever you push something to master repo it will write in a config file which app have to be installed on the next deployment.
    In this week we editing 5 apps which we have to deploy soon – some of them depends each other, some not.
    Now you want to make sure that the apps are published -> installed -> unpublish old version in the right sequence.
    Such a script is amazing 🙂

    It was decreasing our deployment time by around 90%.

      • waldo on August 28, 2019 at 1:36 pm
        Author

      Makes sense, thanks!

    • Kamil Sacek on August 28, 2019 at 12:05 pm
    • Reply

    There are multiple ways for same like:
    Get-NavContainerAppInfo from navcontainerhelper have now new parameter -Sort and will return the dependencies
    Get-ALAppOrder from NVRAppDevOps which works with container and app.json or .app files

      • waldo on August 28, 2019 at 1:33 pm
        Author

      Didn’t know that, thanks!

      Isn’t it limited though to one appfile? Or does it handle multiple files, and take the entire dependency tree into account?

      • Kamil Sacek on August 29, 2019 at 12:39 pm

      No, my Get-ALAppOrder use all, if you have structure like (we have);

      ManApp
      TestApp
      Dependencies (git submodule)
      DepA
      MainApp
      TestApp
      Dependencies
      DepB
      MainApp
      TestApp
      Dependencies

      It will take all app.json and calculate the order. If you have folder of .app files, it will take them, download missing apps from container if they are there (Microsoft apps), download missing apps from another source (we are using nuget Azure DevOps Artifact server), and calculate the order.

      • waldo on August 29, 2019 at 12:40 pm
        Author

      Ok, one evening down the drain 😉

      • Kamil Sacek on August 29, 2019 at 12:40 pm

      Sorry, spaces removed…
      ManApp
      TestApp
      Dependencies (git submodule)
      -DepA
      –MainApp
      –TestApp
      –Dependencies (git submodule)
      -DepB
      –MainApp
      –TestApp
      –Dependencies (git submodule)
      —xxxx

    • Patrick Grabensteiner on August 29, 2019 at 7:46 am
    • Reply

    Very nice solution for publishing, but you have to know in which order you have to compile your apps first 😉

      • waldo on August 29, 2019 at 9:24 am
        Author

      Well, not in my book ;-). Every app has its own build process, its own compilation. I have no need to compile multiple apps at the same time, just download the artifact from the right repository …

      • Srini Arumugam on August 3, 2020 at 12:10 pm

      @patrick, One of the approach is –
      we can publish the app one by one based on the dependency matrix.
      if App B & C is dependant on App A, we can deploy App A first and then B & C (separate or together).

    • Stijn B on October 15, 2019 at 10:20 pm
    • Reply

    Hello,

    I am running this function against an Array of Get-NAVAppInfo’s I collected from a remote server/container. It doesn’t seem to work and I suspect it has something to do with the Invoke-command that is “flattening” the resulting array, hence the subset of dependencies. Any experiences yourself in this approach?

      • waldo on October 16, 2019 at 8:47 am
        Author

      Can you check if the dependency-information is in there? Would be good to be able to play around with it to investigate…

    • Srini Arumugam on August 3, 2020 at 11:03 am
    • Reply

    Waldo,

    If we have app XXXX is dependant on YYYY.
    We deployed v1.0.3 version of XXXX and then deploy v 1.0.8 version of YYYY using ALOps Extension API task (basic Auth)
    is there any way to unpublish v1.0.3 of XXXX only, then deploy v1.0.2 version of XXXX.
    Will the app XXXX and YYYY work as expected.

    Thanks in advance

      • waldo on August 3, 2020 at 11:08 am
        Author

      afaik, there is no way to go back a version – upgrading is not a problem.

    • Srini Arumugam on August 3, 2020 at 12:06 pm
    • Reply

    Waldo, yes that’s grand with not going back to old version.
    Can I check two things based on the deployment failure we had last week,

    1. Below is the snippet of the deployment.
    we had 1.0.0.8 version of XXXX deployed in release 1 using ALOps Extension API task (basic Auth)
    and then in release 2, we again deploy v 1.0.0.8 version of XXXX using ALOps Extension API task (basic Auth) which one of the component deployment as part of the release 2 and we end up with Operation Failed.

    2020-07-31T15:47:00.7689622Z name publisher appVersion operationType schedule status startedOn
    2020-07-31T15:47:00.7702650Z —- ——— ———- ————- ——– —— ———
    2020-07-31T15:47:00.7710617Z AAAA BBBB 1.0.0.8 Upload Immediate Completed 2020-07-31T15:44:10.643Z
    2020-07-31T15:47:00.7719780Z YYYY BBBB 1.0.2.3 Upload Immediate Failed 2020-07-31T15:31:54.49Z
    2020-07-31T15:47:00.7727723Z ZZZZ BBBB 1.0.4.3 Upload Immediate Completed 2020-07-31T15:45:36.377Z
    2020-07-31T15:47:00.7736382Z XXXX BBBB 1.0.0.8 Upload Immediate Failed 2020-07-31T15:47:00.47Z
    is there a way to mitigate this scenario.

    2. In ALOps Extension API task (basic Auth), is there an option to check whether version 1.0.0.8 version of XXXX is already deployed and hence no need to deploy it again in release 2.

    Thanks in advance.

    Regards
    Srini

    • Srini Arumugam on August 3, 2020 at 12:08 pm
    • Reply

    Error details for Operation Failed. A different .app file with the same App ID (b0a7c46a-77a3-4385-a34f-4ea80173e378) and version (1.0.0.8) has already been uploaded to an environment in our service. Please verify that the App ID assigned to this extension is the correct one, increment the version number to one that has not been used, and redeploy the package. Read more here https://go.microsoft.com/fwlink/?linkid=2128807 .

  1. […] App Dependency Tree – import your apps in the right order (with PowerShell) […]

  2. […] Source : Waldo’s blog Read more… […]

  3. […] You can find out how to import your apps in the right order using PowerShell here. […]

  4. […] script – would be nice to have one script that figures our the dependency tree (I already got that one), and invoke start compiling all the apps – and – may be – if possible – […]

  5. […] script will compile all apps in your Multi Root Workspace, in the right order (it will use the scripts I blogged about here to determine the order).  And then it will call the “Compile-ALApp” that’s […]

  6. […] script will compile all apps in your Multi Root Workspace, in the right order (it will use the scripts I blogged about here to determine the order).  And then it will call the “Compile-ALApp” that’s […]

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.