AL icon indicating copy to clipboard operation
AL copied to clipboard

directory.app.props.json file runtime property not being set in compiled app

Open BW-PA opened this issue 2 months ago • 7 comments

Please include the following with each issue:

1. Describe the bug I created a multi app workspace and utilised the new directory.apps.props.json file to set various properties in my apps. One property in particular is not flowing through to the compiled app file. The property in question is runtime property.

I set runtime to 15.2 in the directory.apps.props.json file and removed it from App.json in App1 but left it there in App2 and App3 app.json files.

My expectation is that app1 compile artifact (*.app) will be compiled to the value set by directory.apps.props.json (since it's own app.json does not specify the runtime property. App2 and App3 compiled app files will contain the runtime value from their respective app.json files since the runtime property is present there.

However, when I build App1 (expecting runtime 15.2 as defined in directory.apps.props.json) it actually gets a runtime of 17.

2. To Reproduce

  1. Create a multi project workspace with 3 app folders.
  2. Create a directory.app.props.json
{
    "variables": {
        "major": "25",
        "minor": "1",
        "build": "1",
        "revision": "2",
        "version": "$(major).$(minor).$(build).$(revision)"
    },
    "properties": {
        "publisher": "Fabrikam",
        "runtime": "15.2",
        "application": "25.0.0.0",
        "platform": "25.0.0.0"
    }
}
  1. edit App1's app.json to remove publisher, runtime, application and platform properties.
  2. compile App1
  3. open compiled app in 7zip
  4. open NavxManifest.xml and check the values and see that all are set based off properties in directory.app.props.json EXCEPT runtime, which should be 15.2 but is actually 17.0
<Package xmlns="http://schemas.microsoft.com/navx/2015/manifest">
<App Id="c9f93b54-869f-4b75-8242-0d8236b21ec1" Name="App1" Publisher="Fabrikam" Brief="" Description="" Version="25.1.1.2" CompatibilityId="0.0.0.0" PrivacyStatement="" EULA="" Help="" HelpBaseUrl="" Url="" Logo="" Platform="25.0.0.0" Application="25.0.0.0" Runtime="17.0" Target="Cloud" ShowMyCode="False"/>
<IdRanges>
<IdRange MinObjectId="50100" MaxObjectId="50149"/>
</IdRanges>
<Dependencies/>
<InternalsVisibleTo/>
<ScreenShots/>
<SupportedLocales/>
<Features>
<Feature>NOIMPLICITWITH</Feature>
</Features>
<PreprocessorSymbols/>
<SuppressWarnings/>
<ResourceExposurePolicy AllowDebugging="true" AllowDownloadingSource="true" IncludeSourceInSymbolFile="true" ApplyToDevExtension="false"/>
<KeyVaultUrls/>
<Source/>
<Build By="AL Language Extension,17.0.1860968" Timestamp="2025-10-20T05:50:16.6536797Z" CompilerVersion="17.0.28.26016"/>
<AlternateIds/>
</Package>

Repo containing my sample that demonstrates the issue https://github.com/Professional-Advantage-SDG/Props-Json-Spike

directory.app.props.json

Note: Because the developers need to copy and paste the code snippet, including a code snippet as a media file (i.e. .gif) is not sufficient.

3. Expected behavior Expecting compiled app to contain the runtime value set in the directory.app.props.json file

4. Actual behavior manifest contains runtime 17.0 and attempting to install the app into a BC version 26 environment results in an error regarding runtime and version 17,

5. Versions:

  • AL Language: 17.0.1860968
  • Visual Studio Code: 1.105.1
  • Business Central: v26.5
  • List of Visual Studio Code extensions that you have installed: AL
  • Operating System:
    • [X] Windows
    • [ ] Linux
    • [ ] MacOS

Final Checklist

Please remember to do the following:

  • [X] Search the issue repository to ensure you are reporting a new issue

  • [X] Reproduce the issue after disabling all extensions except the AL Language extension

  • [X] Simplify your code around the issue to better isolate the problem

Internal work item: AB#611205

BW-PA avatar Oct 20 '25 06:10 BW-PA

Isn't it because directory.app.props.json is supported from BC27 and AL16 (min. runtime 16.0)? And did you try it with AL release version 16.1 instead of preview?

RadoArvay avatar Oct 20 '25 14:10 RadoArvay

Isn't it because directory.app.props.json is supported from BC27 and AL16 (min. runtime 16.0)? And did you try it with AL release version 16.1 instead of preview?

Thanks for that suggestion. I changed the AL extension back to 16.1

Image

And recompiled and the runtime in NavxManifest.xml did change from 17 to 16

<Package xmlns="http://schemas.microsoft.com/navx/2015/manifest">
<App Id="c9f93b54-869f-4b75-8242-0d8236b21ec1" Name="App1" Publisher="Fabrikam" Brief="" Description="" Version="25.1.1.2" CompatibilityId="0.0.0.0" PrivacyStatement="" EULA="" Help="" HelpBaseUrl="" Url="" Logo="" Platform="25.0.0.0" Application="25.0.0.0" Runtime="16.0" Target="Cloud" ShowMyCode="False"/>
<IdRanges>
<IdRange MinObjectId="50100" MaxObjectId="50149"/>
</IdRanges>
<Dependencies/>
<InternalsVisibleTo/>
<ScreenShots/>
<SupportedLocales/>
<Features>
<Feature>NOIMPLICITWITH</Feature>
</Features>
<PreprocessorSymbols/>
<SuppressWarnings/>
<ResourceExposurePolicy AllowDebugging="true" AllowDownloadingSource="true" IncludeSourceInSymbolFile="true" ApplyToDevExtension="false"/>
<KeyVaultUrls/>
<Source/>
<Build By="AL Language Extension,16.1.1860725" Timestamp="2025-10-21T04:50:15.7026962Z" CompilerVersion="16.1.28.25773"/>
<AlternateIds/>
</Package>

However, my issue still stands. I had set the runtime for the above XML output to 16.1 in the below directory.app.props.json file and the runtime property did not flow through to the compiled artifact.

{
    "variables": {
        "major": "25",
        "minor": "1",
        "build": "1",
        "revision": "3",
        "version": "$(major).$(minor).$(build).$(revision)"
    },
    "properties": {
        "publisher": "Fabrikam",
        "runtime": "16.1",
        "application": "25.0.0.0",
        "platform": "25.0.0.0"
    }
}

MS Documentation lists runtime as a supported property. The other properties flow through fine though. Just not runtime.

BW-PA avatar Oct 21 '25 05:10 BW-PA

Yes, runtime is supported and I have already used it. And it worked - but I do not remember the runtime in built apps. Unfortunately, directory.app.props.json brings many other problems related to other VSC extensions, so I switched the workspace back to old explicit app.json configurations.

Let me rephrase it (but it is a question to Microsoft): directory.app.props.json came with BC27 and runtime 16.0 as minimum. You are trying to use it with platform/application BC25, where maximal runtime is 15.x. Maybe that could be a reason...??

RadoArvay avatar Oct 21 '25 07:10 RadoArvay

I didn't experience problems with other VSC extensions. But did remove all others except for AL to log this ticket just in case. I understand your point about directory.app.props.json being a BC27 and runtime 16.0 onwards feature. Though should that matter?

My understanding may be too simplistic but my expectation of how it should work is that you set whatever value you like in directory.app.props.json and the app gets compiled with those values. Or said another way. The compiler gets passed the values from directory.app.props.json just like it does with app.json normally.

directory.app.props.json should just be a master template for setting the values passed to the compiler. Therefore, if I set runtime in directory.app.props.json I expect that value to be passed to the compiler and used in the compiled app (assuming it doesn't conflict with the compiler validation. A runtime of 99.0 for example shouldn't work because that's not a current valid runtime value)

To test further I setup another comparison.

Scenario 1 - Standard app.json handling

app.json settings (not realistic values but technically valid values. I did it this way to see how standard process works) "application": "27.0.0.0", "runtime": "15.1",

Resulting NavxManifest received "application": "27.0.0.0", "runtime": "15.1",

<Package xmlns="http://schemas.microsoft.com/navx/2015/manifest">
<App Id="75dc336e-cd24-4316-bc20-9f44d413d4b7" Name="App2" Publisher="Default Publisher" Brief="" Description="" Version="1.0.0.0" CompatibilityId="0.0.0.0" PrivacyStatement="" EULA="" Help="" HelpBaseUrl="" Url="" Logo="" Platform="1.0.0.0" Application="27.0.0.0" Runtime="15.1" Target="Cloud" ShowMyCode="False"/>
<IdRanges>
<IdRange MinObjectId="50150" MaxObjectId="50199"/>
</IdRanges>
<Dependencies/>
<InternalsVisibleTo/>
<ScreenShots/>
<SupportedLocales/>
<Features>
<Feature>NOIMPLICITWITH</Feature>
</Features>
<PreprocessorSymbols/>
<SuppressWarnings/>
<ResourceExposurePolicy AllowDebugging="true" AllowDownloadingSource="true" IncludeSourceInSymbolFile="true" ApplyToDevExtension="false"/>
<KeyVaultUrls/>
<Source/>
<Build By="AL Language Extension,16.1.1860725" Timestamp="2025-10-22T00:02:30.8816140Z" CompilerVersion="16.1.28.25773"/>
<AlternateIds/>
</Package>

Scenario 2 - directory.app.props.json handling

directory.app.props.json settings (again not realistic values but did it this way to compare with standard app.json process) "application": "27.0.0.0", "runtime": "15.1",

Resulting NavxManifest received "application": "27.0.0.0", "runtime": "16.0",

<Package xmlns="http://schemas.microsoft.com/navx/2015/manifest">
<App Id="c9f93b54-869f-4b75-8242-0d8236b21ec1" Name="App1" Publisher="Fabrikam" Brief="" Description="" Version="25.1.1.4" CompatibilityId="0.0.0.0" PrivacyStatement="" EULA="" Help="" HelpBaseUrl="" Url="" Logo="" Platform="27.0.0.0" Application="27.0.0.0" Runtime="16.0" Target="Cloud" ShowMyCode="False"/>
<IdRanges>
<IdRange MinObjectId="50100" MaxObjectId="50149"/>
</IdRanges>
<Dependencies/>
<InternalsVisibleTo/>
<ScreenShots/>
<SupportedLocales/>
<Features>
<Feature>NOIMPLICITWITH</Feature>
</Features>
<PreprocessorSymbols/>
<SuppressWarnings/>
<ResourceExposurePolicy AllowDebugging="true" AllowDownloadingSource="true" IncludeSourceInSymbolFile="true" ApplyToDevExtension="false"/>
<KeyVaultUrls/>
<Source/>
<Build By="AL Language Extension,16.1.1860725" Timestamp="2025-10-22T00:08:43.8482723Z" CompilerVersion="16.1.28.25773"/>
<AlternateIds/>
</Package>

If the standard processing using the same AL extension version ("AL Language Extension,16.1.1860725") supports passing through the runtime to the compiled app. And the directory.app.props.json is just a wrapper on top of the standard app.json properties being passed to the compiler. Is it a fair expectation that directory.app.props.json should behave the same way as the standard app.json handling?

BW-PA avatar Oct 22 '25 00:10 BW-PA

Hi,

This might be a slightly broader topic, but I’d still like to mention.

I have one more comment regarding directory.app.props.json. Since this feature was introduced, the text output of compiler has become insufficient. It no longer shows what file was actually generated. Without this information, it’s no longer easy to identify the output file and use it for further processing.

I would expect at least the output described here: the same format shown in this idea: https://experience.dynamics.com/ideas/idea/?ideaid=771fef16-8f98-ef11-95f5-6045bdc01d6d

zabcik avatar Nov 18 '25 08:11 zabcik

Hi,

This might be a slightly broader topic, but I’d still like to mention.

I have one more comment regarding directory.app.props.json. Since this feature was introduced, the text output of compiler has become insufficient. It no longer shows what file was actually generated. Without this information, it’s no longer easy to identify the output file and use it for further processing.

I would expect at least the output described here: the same format shown in this idea: https://experience.dynamics.com/ideas/idea/?ideaid=771fef16-8f98-ef11-95f5-6045bdc01d6d

This sounds like a different issue to the one I have logged and would likely benefit from having its own issue raised if you haven't done so already.

BW-PA avatar Nov 19 '25 22:11 BW-PA

@zabcik It's worse. It's loaded using a json loader (not jsonc/json5) unlike app.json (nowadays). This means you get impossible errors attributed to app.json. (and no comments in the props file) "target" fails just like "runtime". No warnings if you mis-spell any config tag. Other valid structures like putting an array on any tag (including ignored ones) gives "cannot convert to system.string". Wonderful messages like "The manifest properties 'baseHelpUrl' and 'supportedLocales' must both be specified and have values." when both are indeed specified but it ignores one of them. Or maybe it looks like none of them are defined if you don't know there's an props file there. Oh and don't try to use the "logo" property with a relative path, there's probably a 40% chance Microsoft will change it when they realise it might be inconsistent.

Most of this is probably because it's just a bad design to start with; hunting for a config variables file is a poor design idea if you don't have any variables to search for. Or to put it bluntly the "properties" section of directory.app.props.json should not exist. It's function, should be embedded in app.json. If you're scared that someone has put "$(" into one of their URLs then invent new dynamic tags like "EULA.d". Or just use the "glob" (or preprocessor or many template engines) form of failing were any variable reference that has any sort of error or doesn't match a defined variable is left textually unchanged.

PS: Oh, yes and it has no embedded documentation (in the vscode AL extension). The AL extension doesn't recognise the file and doesn't give any auto-completes or warnings even if it's in the same directory as the app.json.

rdebath avatar Dec 11 '25 07:12 rdebath