Remember my blog post on “Multi-root workspaces in VSCode for AL Development“?  If not – it might be interesting to read first, because this is in fact an “extension” (get it?) on it .. so you might say this blogpost “depends” on that one ;-).

I concluded the post with some scripts – and that’s the part I’d like to extend a bit – because I needed more functionality since latest blogpost.  And I’d like to refer to these scripts again – and tell you a bit more on how they could make your life a bit easier as well .. .


The main part that I extended is the “Git”-part.  And as an example, I’d want to take you to this blog post from Michael Megel.  Michael talks about the “Release flow” – and how much it makes sense for ISV partners in Business Central.  Well .. now take into account the multitude of apps that we might have.  In our company, we have 22 apps at this moment (x2 if you count the corresponding test-apps as well). 

In terms of Git/DevOps, that’s 22 repositories.  In terms of VSCode, that’s 44 workspaces.  In terms of release management: that’s branching 22 repositories the very same: if I need to create a release branch, I need to create the same release branch over all repositories at the same time.

So indeed – we choose to NOT have a release per app – but rather have one release for all apps – so when we create a release branch – we basically have to create the same branch-name in all apps.  Fairly simple – but if you have to do that manually for 22 repos – that’s going to be tedious (and any repetitive job that is executed manually, just cries for mistakes). 

This is just one example of many that needs to be solved when you have multiple apps/workspaces/.. .


Indeed – that’s where scripting comes into place.  And having a multi-root workspace in combination with some PowerShell Scripts, just makes your life a bit easier.  Do notice though that I’m not making my scripts part of the multi root workspace.  That just doesn’t work – the Al Language Extension does “something” with the F5 key that kind of like disables the ability to run any PowerShell script that’s part of the same Multi Root environment (F8 does work – but I need F5 ;-)).  So – I always have a second VSCode open with my PS Scripts.

The scripts

The scripts are still located in the same place as mentioned in my previous blog, but I have more now.  So you have more now as well ;-).  Do notice it’s based on my PowerShell modules.  So I do advice you to install them, or not everything might work (thank you for the download count ;-)).  So – this is what I have today:


Make sure all variables are correct in this file – otherwise all below scripts won’t work correctly.  As you can see in this script, it will not look at any workspace-file, but it find all app.json-files and treat all directories as “targets” for where to execute the below scripts.  I might change that behaviour in the future though – I don’t know yet – this works for me now ;-).


This 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 part of my module “Cloud.Ready.Software.NAV“, which will use the alc.exe in your user profile (basically from the AL Language extension in VSCode) to compile the app.  I don’t use this script too of the though – only when I really need to for example have all updated translations files.


Well – if you use one Dev environment, for all your apps – it’s good to have one vscode-file for all workspace.  I know there is a way to update your workspace file with configurations – but I personally don’t use that.  At least this way, I’m still able to easily just open the individual workspace, and still use the right launch.json.


This is a strange one.  This script is actually going to copy a command to my clipboard that I can execute in the terminal of my MultiRoot workspace. It will open all App.json files.  Few reasons would be interesting:

  • you would like to manually open all manifests to do a similar change to all of them
  • You would like to just open a file of all workspaces to start the AL Compile and find all code analysis problems in one go (an app is only compiled when one of its files are opened)


This script will remove all symbol files from all workspaces.  Especially when you change localization or version, this is really useful.


Yep – a loop for downloading all symbols for all workpaces.  It isn’t very useful though because in a fresh environment, it will most likely not be able to download all symbols – although, when I start a very clean environment, I usually cleanup all symbols and run this once – then at least I have “most” of them.  It doesn’t hurt to run this in the background ;-).


Simple loop to put all translation-files in one zip-file.  Easy to mail to your translator.


This is where the branching comes in play.  This script will first synchronize master, and then start a new branch, all with the same name, for all your workpaces.  Especially interesting to synch branch-naming for multiple repositories (like necessary in this Release Flow as mentioned earlier).


Just imagine, you messed up – and you don’t want to do some kind of edit in all your workspaces, and want to execute a “Discard All” on all your workspaces.  That’s exactly what this script does.


If you don’t want to discard, but edited files in all your workspaces, and you want the same commit message for all your repositories: just a script that does loop through your repos, and will stage and commit with that same message.


This doesn’t need too much explanation: it will switch the branch to another branch.


Again – exactly like it says – it will update the master-branch for all your workspaces.


This one will update a branch from master branch.  It will first sync the master branch (make sure it’s up-to-date with the remote), and then update the selected branch with master.  This might result in conflicts, which you have time to solve in VSCode.

So, on which workflows do you use it?

They are very useful in many scenarios .. .  Let me explain a few of them.. .


We try to translate in batches (no – developers are no translators.  Development languages or not “normal” languages, you know ;-)).  As such: send a bunch of translation files to the one that will translate.  When I get that back, I will import the files, and commit. The workflow is something like:

  • Create a branch for all workspaces (Script: Git_CreateBranchFromMaster)
    • Usually called “Translation”
  • Compile all to create an updated .g.xlf file (Script: Apps_CompileAll)
  • Use VSCode “XLIFFSync” extension to update all translated files
  • Commit “Before Translation” to git (Script: Git_StageAndCommit)
  • Create a zip-file (Script: Apps_ZipTranslation)
  • Import translated files to the right folders (manually)
  • Commit “After Translation” to git (Script: Git_StageAndCommit)
  • Pullrequest all changes to master (Manually in DevOps – Intentionally – I want PRs to be manual at all times (for now))

Release Flow

As mentioned above – there are many scenarios where you would like to “sync branch names” across multiple repositories, like creating the same release-branch for multiple repositories in an AL Dependency Architecture.


  • Create a branch for all workspaces (Script: Git_CreateBranchFromMaster)
  • Create/modify the pipelines (usually yml files across all repos)
  • Commit to git (Script: Git_StageAndCommit)
  • Secure you branch in DevOps (Branch Policies)

Major upgrades

Microsoft comes with new major release twice a year.  And for major upgrades, it usually takes some time to prepare your stuff for the next upgrade.  We simply follow this workflow:

  • Create a branch for all workspaces (Script: Git_CreateBranchFromMaster)
  • Fix a particular problem
  • Commit to git (Script: Git_StageAndCommit)
  • Pullrequest to master when done (manually in DevOps)

And probably steps 2 and 3 has to be repeated a few times – and that’s again where the scripts become very useful ;-).


If you are a heavy user of multi root workspaces in AL Development – give these scripts a spin.  I encourage you ;-).